early-access version 1255

This commit is contained in:
pineappleEA
2020-12-28 15:15:37 +00:00
parent 84b39492d1
commit 78b48028e1
6254 changed files with 1868140 additions and 0 deletions

182
externals/libressl/crypto/bio/b_dump.c vendored Executable file
View File

@@ -0,0 +1,182 @@
/* $OpenBSD: b_dump.c,v 1.21 2015/04/23 06:11:19 deraadt Exp $ */
/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
* All rights reserved.
*
* This package is an SSL implementation written
* by Eric Young (eay@cryptsoft.com).
* The implementation was written so as to conform with Netscapes SSL.
*
* This library is free for commercial and non-commercial use as long as
* the following conditions are aheared to. The following conditions
* apply to all code found in this distribution, be it the RC4, RSA,
* lhash, DES, etc., code; not just the SSL code. The SSL documentation
* included with this distribution is covered by the same copyright terms
* except that the holder is Tim Hudson (tjh@cryptsoft.com).
*
* Copyright remains Eric Young's, and as such any Copyright notices in
* the code are not to be removed.
* If this package is used in a product, Eric Young should be given attribution
* as the author of the parts of the library used.
* This can be in the form of a textual message at program startup or
* in documentation (online or textual) provided with the package.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* "This product includes cryptographic software written by
* Eric Young (eay@cryptsoft.com)"
* The word 'cryptographic' can be left out if the rouines from the library
* being used are not cryptographic related :-).
* 4. If you include any Windows specific code (or a derivative thereof) from
* the apps directory (application code) you must include an acknowledgement:
* "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
*
* THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* The licence and distribution terms for any publically available version or
* derivative of this code cannot be changed. i.e. this code cannot simply be
* copied and put under another distribution licence
* [including the GNU Public Licence.]
*/
/*
* Stolen from tjh's ssl/ssl_trc.c stuff.
*/
#include <stdio.h>
#include <string.h>
#include <openssl/bio.h>
#define TRUNCATE
#define DUMP_WIDTH 16
#define DUMP_WIDTH_LESS_INDENT(i) (DUMP_WIDTH - ((i - (i > 6 ? 6 : i) + 3) / 4))
int
BIO_dump_cb(int (*cb)(const void *data, size_t len, void *u),
void *u, const char *s, int len)
{
return BIO_dump_indent_cb(cb, u, s, len, 0);
}
int
BIO_dump_indent_cb(int (*cb)(const void *data, size_t len, void *u),
void *u, const char *s, int len, int indent)
{
int ret = 0;
char buf[288 + 1], tmp[20], str[128 + 1];
int i, j, rows, trc;
unsigned char ch;
int dump_width;
trc = 0;
#ifdef TRUNCATE
for (; (len > 0) && ((s[len - 1] == ' ') || (s[len - 1] == '\0')); len--)
trc++;
#endif
if (indent < 0)
indent = 0;
if (indent) {
if (indent > 128)
indent = 128;
memset(str, ' ', indent);
}
str[indent] = '\0';
dump_width = DUMP_WIDTH_LESS_INDENT(indent);
rows = (len / dump_width);
if ((rows * dump_width) < len)
rows++;
for (i = 0; i < rows; i++) {
strlcpy(buf, str, sizeof buf);
snprintf(tmp, sizeof tmp, "%04x - ", i*dump_width);
strlcat(buf, tmp, sizeof buf);
for (j = 0; j < dump_width; j++) {
if (((i*dump_width) + j) >= len) {
strlcat(buf, " ", sizeof buf);
} else {
ch = ((unsigned char)*(s + i*dump_width + j)) & 0xff;
snprintf(tmp, sizeof tmp, "%02x%c", ch,
j == 7 ? '-' : ' ');
strlcat(buf, tmp, sizeof buf);
}
}
strlcat(buf, " ", sizeof buf);
for (j = 0; j < dump_width; j++) {
if (((i*dump_width) + j) >= len)
break;
ch = ((unsigned char)*(s + i * dump_width + j)) & 0xff;
snprintf(tmp, sizeof tmp, "%c",
((ch >= ' ') && (ch <= '~')) ? ch : '.');
strlcat(buf, tmp, sizeof buf);
}
strlcat(buf, "\n", sizeof buf);
/* if this is the last call then update the ddt_dump thing so
* that we will move the selection point in the debug window
*/
ret += cb((void *)buf, strlen(buf), u);
}
#ifdef TRUNCATE
if (trc > 0) {
snprintf(buf, sizeof buf, "%s%04x - <SPACES/NULS>\n",
str, len + trc);
ret += cb((void *)buf, strlen(buf), u);
}
#endif
return (ret);
}
static int
write_fp(const void *data, size_t len, void *fp)
{
return fwrite(data, 1, len, fp);
}
int
BIO_dump_fp(FILE *fp, const char *s, int len)
{
return BIO_dump_cb(write_fp, fp, s, len);
}
int
BIO_dump_indent_fp(FILE *fp, const char *s, int len, int indent)
{
return BIO_dump_indent_cb(write_fp, fp, s, len, indent);
}
static int
write_bio(const void *data, size_t len, void *bp)
{
return BIO_write((BIO *)bp, (const char *)data, len);
}
int
BIO_dump(BIO *bp, const char *s, int len)
{
return BIO_dump_cb(write_bio, bp, s, len);
}
int
BIO_dump_indent(BIO *bp, const char *s, int len, int indent)
{
return BIO_dump_indent_cb(write_bio, bp, s, len, indent);
}

90
externals/libressl/crypto/bio/b_posix.c vendored Executable file
View File

@@ -0,0 +1,90 @@
/* $OpenBSD: b_posix.c,v 1.2 2018/03/17 16:20:01 beck Exp $ */
/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
* All rights reserved.
*
* This package is an SSL implementation written
* by Eric Young (eay@cryptsoft.com).
* The implementation was written so as to conform with Netscapes SSL.
*
* This library is free for commercial and non-commercial use as long as
* the following conditions are aheared to. The following conditions
* apply to all code found in this distribution, be it the RC4, RSA,
* lhash, DES, etc., code; not just the SSL code. The SSL documentation
* included with this distribution is covered by the same copyright terms
* except that the holder is Tim Hudson (tjh@cryptsoft.com).
*
* Copyright remains Eric Young's, and as such any Copyright notices in
* the code are not to be removed.
* If this package is used in a product, Eric Young should be given attribution
* as the author of the parts of the library used.
* This can be in the form of a textual message at program startup or
* in documentation (online or textual) provided with the package.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* "This product includes cryptographic software written by
* Eric Young (eay@cryptsoft.com)"
* The word 'cryptographic' can be left out if the rouines from the library
* being used are not cryptographic related :-).
* 4. If you include any Windows specific code (or a derivative thereof) from
* the apps directory (application code) you must include an acknowledgement:
* "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
*
* THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* The licence and distribution terms for any publically available version or
* derivative of this code cannot be changed. i.e. this code cannot simply be
* copied and put under another distribution licence
* [including the GNU Public Licence.]
*/
/*
* Functions that need to be overridden by non-POSIX operating systems.
*/
#include <fcntl.h>
#include <unistd.h>
#include <openssl/bio.h>
int
BIO_sock_init(void)
{
if (!OPENSSL_init_crypto(0, NULL)) /* XXX do we need this? */
return (0);
return (1);
}
void
BIO_sock_cleanup(void)
{
}
int
BIO_socket_nbio(int s, int mode)
{
int flags = fcntl(s, F_GETFD);
if (mode && !(flags & O_NONBLOCK))
return (fcntl(s, F_SETFL, flags | O_NONBLOCK) != -1);
else if (!mode && (flags & O_NONBLOCK))
return (fcntl(s, F_SETFL, flags & ~O_NONBLOCK) != -1);
return (1);
}

106
externals/libressl/crypto/bio/b_print.c vendored Executable file
View File

@@ -0,0 +1,106 @@
/* $OpenBSD: b_print.c,v 1.26 2019/06/28 05:47:57 deraadt Exp $ */
/* Theo de Raadt places this file in the public domain. */
#include <openssl/bio.h>
int
BIO_printf(BIO *bio, const char *format, ...)
{
va_list args;
int ret;
va_start(args, format);
ret = BIO_vprintf(bio, format, args);
va_end(args);
return (ret);
}
#ifdef HAVE_FUNOPEN
static int
_BIO_write(void *cookie, const char *buf, int nbytes)
{
return BIO_write(cookie, buf, nbytes);
}
int
BIO_vprintf(BIO *bio, const char *format, va_list args)
{
int ret;
FILE *fp;
fp = funopen(bio, NULL, &_BIO_write, NULL, NULL);
if (fp == NULL) {
ret = -1;
goto fail;
}
ret = vfprintf(fp, format, args);
fclose(fp);
fail:
return (ret);
}
#else /* !HAVE_FUNOPEN */
int
BIO_vprintf(BIO *bio, const char *format, va_list args)
{
int ret;
char *buf = NULL;
ret = vasprintf(&buf, format, args);
if (ret == -1)
return (ret);
BIO_write(bio, buf, ret);
free(buf);
return (ret);
}
#endif /* HAVE_FUNOPEN */
/*
* BIO_snprintf and BIO_vsnprintf return -1 for overflow,
* due to the history of this API. Justification:
*
* Traditional snprintf surfaced in 4.4BSD, and returned
* "number of bytes wanted". Solaris and Windows opted to
* return -1. A draft standard was written which returned -1.
* Due to the large volume of code already using the first
* semantics, the draft was repaired before standardization to
* specify "number of bytes wanted" plus "-1 for character conversion
* style errors". Solaris adapted to this rule, but Windows stuck
* with -1.
*
* Original OpenSSL comment which is full of lies:
*
* "In case of truncation, return -1 like traditional snprintf.
* (Current drafts for ISO/IEC 9899 say snprintf should return
* the number of characters that would have been written,
* had the buffer been large enough.)"
*/
int
BIO_snprintf(char *buf, size_t n, const char *format, ...)
{
va_list args;
int ret;
va_start(args, format);
ret = vsnprintf(buf, n, format, args);
va_end(args);
if (ret >= n || ret == -1)
return (-1);
return (ret);
}
int
BIO_vsnprintf(char *buf, size_t n, const char *format, va_list args)
{
int ret;
ret = vsnprintf(buf, n, format, args);
if (ret >= n || ret == -1)
return (-1);
return (ret);
}

243
externals/libressl/crypto/bio/b_sock.c vendored Executable file
View File

@@ -0,0 +1,243 @@
/* $OpenBSD: b_sock.c,v 1.69 2018/02/07 00:52:05 bluhm Exp $ */
/*
* Copyright (c) 2017 Bob Beck <beck@openbsd.org>
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#include <sys/ioctl.h>
#include <sys/socket.h>
#include <string.h>
#include <arpa/inet.h>
#include <netinet/in.h>
#include <netinet/tcp.h>
#include <errno.h>
#include <limits.h>
#include <netdb.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <openssl/bio.h>
#include <openssl/buffer.h>
#include <openssl/err.h>
int
BIO_get_host_ip(const char *str, unsigned char *ip)
{
struct addrinfo *res = NULL;
struct addrinfo hints = {
.ai_family = AF_INET,
.ai_socktype = SOCK_STREAM,
.ai_flags = AI_PASSIVE,
};
uint32_t *iap = (in_addr_t *)ip;
int error;
if (str == NULL) {
ERR_asprintf_error_data("NULL host provided");
return (0);
}
if ((error = getaddrinfo(str, NULL, &hints, &res)) != 0) {
BIOerror(BIO_R_BAD_HOSTNAME_LOOKUP);
ERR_asprintf_error_data("getaddrinfo: host='%s' : %s'", str,
gai_strerror(error));
return (0);
}
*iap = (uint32_t)(((struct sockaddr_in *)(res->ai_addr))->sin_addr.s_addr);
freeaddrinfo(res);
return (1);
}
int
BIO_get_port(const char *str, unsigned short *port_ptr)
{
struct addrinfo *res = NULL;
struct addrinfo hints = {
.ai_family = AF_UNSPEC,
.ai_socktype = SOCK_STREAM,
.ai_flags = AI_PASSIVE,
};
int error;
if (str == NULL) {
BIOerror(BIO_R_NO_PORT_SPECIFIED);
return (0);
}
if ((error = getaddrinfo(NULL, str, &hints, &res)) != 0) {
ERR_asprintf_error_data("getaddrinfo: service='%s' : %s'", str,
gai_strerror(error));
return (0);
}
*port_ptr = ntohs(((struct sockaddr_in *)(res->ai_addr))->sin_port);
freeaddrinfo(res);
return (1);
}
int
BIO_sock_error(int sock)
{
socklen_t len;
int err;
len = sizeof(err);
if (getsockopt(sock, SOL_SOCKET, SO_ERROR, &err, &len) != 0)
return (1);
return (err);
}
struct hostent *
BIO_gethostbyname(const char *name)
{
return gethostbyname(name);
}
int
BIO_socket_ioctl(int fd, long type, void *arg)
{
int ret;
ret = ioctl(fd, type, arg);
if (ret < 0)
SYSerror(errno);
return (ret);
}
int
BIO_get_accept_socket(char *host, int bind_mode)
{
struct addrinfo hints = {
.ai_family = AF_INET,
.ai_socktype = SOCK_STREAM,
.ai_flags = AI_PASSIVE,
};
struct addrinfo *res = NULL;
char *h, *p, *str = NULL;
int error, ret = 0, s = -1;
if (host == NULL || (str = strdup(host)) == NULL)
return (-1);
p = NULL;
h = str;
if ((p = strrchr(str, ':')) == NULL) {
/* A string without a colon is treated as a port. */
p = str;
h = NULL;
} else {
*p++ = '\0';
if (*p == '\0') {
BIOerror(BIO_R_NO_PORT_SPECIFIED);
goto err;
}
if (*h == '\0' || strcmp(h, "*") == 0)
h = NULL;
}
if ((error = getaddrinfo(h, p, &hints, &res)) != 0) {
ERR_asprintf_error_data("getaddrinfo: '%s:%s': %s'", h, p,
gai_strerror(error));
goto err;
}
if (h == NULL) {
struct sockaddr_in *sin = (struct sockaddr_in *)res->ai_addr;
sin->sin_addr.s_addr = INADDR_ANY;
}
s = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
if (s == -1) {
SYSerror(errno);
ERR_asprintf_error_data("host='%s'", host);
BIOerror(BIO_R_UNABLE_TO_CREATE_SOCKET);
goto err;
}
if (bind_mode == BIO_BIND_REUSEADDR) {
int i = 1;
ret = setsockopt(s, SOL_SOCKET, SO_REUSEADDR, &i, sizeof(i));
bind_mode = BIO_BIND_NORMAL;
}
if (bind(s, res->ai_addr, res->ai_addrlen) == -1) {
SYSerror(errno);
ERR_asprintf_error_data("host='%s'", host);
BIOerror(BIO_R_UNABLE_TO_BIND_SOCKET);
goto err;
}
if (listen(s, SOMAXCONN) == -1) {
SYSerror(errno);
ERR_asprintf_error_data("host='%s'", host);
BIOerror(BIO_R_UNABLE_TO_LISTEN_SOCKET);
goto err;
}
ret = 1;
err:
free(str);
if (res != NULL)
freeaddrinfo(res);
if ((ret == 0) && (s != -1)) {
close(s);
s = -1;
}
return (s);
}
int
BIO_accept(int sock, char **addr)
{
char h[NI_MAXHOST], s[NI_MAXSERV];
struct sockaddr_in sin;
socklen_t sin_len = sizeof(sin);
int ret = -1;
if (addr == NULL)
goto end;
ret = accept(sock, (struct sockaddr *)&sin, &sin_len);
if (ret == -1) {
if (BIO_sock_should_retry(ret))
return -2;
SYSerror(errno);
BIOerror(BIO_R_ACCEPT_ERROR);
goto end;
}
/* XXX Crazy API. Can't be helped */
if (*addr != NULL) {
free(*addr);
*addr = NULL;
}
if (sin.sin_family != AF_INET)
goto end;
if (getnameinfo((struct sockaddr *)&sin, sin_len, h, sizeof(h),
s, sizeof(s), NI_NUMERICHOST|NI_NUMERICSERV) != 0)
goto end;
if ((asprintf(addr, "%s:%s", h, s)) == -1) {
BIOerror(ERR_R_MALLOC_FAILURE);
*addr = NULL;
goto end;
}
end:
return (ret);
}
int
BIO_set_tcp_ndelay(int s, int on)
{
return (setsockopt(s, IPPROTO_TCP, TCP_NODELAY, &on, sizeof(on)) == 0);
}

54
externals/libressl/crypto/bio/b_win.c vendored Executable file
View File

@@ -0,0 +1,54 @@
/*
* Public domain
*
* Dongsheng Song <dongsheng.song@gmail.com>
* Brent Cook <bcook@openbsd.org>
*/
#include <ws2tcpip.h>
#include <openssl/bio.h>
#include <openssl/err.h>
int
BIO_sock_init(void)
{
/*
* WSAStartup loads the winsock .dll and initializes the networking
* stack on Windows, or simply increases the reference count.
*/
static struct WSAData wsa_state = {0};
WORD version_requested = MAKEWORD(2, 2);
static int wsa_init_done = 0;
if (!wsa_init_done) {
if (WSAStartup(version_requested, &wsa_state) != 0) {
int err = WSAGetLastError();
SYSerror(err);
BIOerror(BIO_R_WSASTARTUP);
return (-1);
}
wsa_init_done = 1;
}
return (1);
}
void
BIO_sock_cleanup(void)
{
/*
* We could call WSACleanup here, but it is easy to get it wrong. Since
* this API provides no way to even tell if it failed, there is no safe
* way to expose that functionality here.
*
* The cost of leaving the networking DLLs loaded may have been large
* during the Windows 3.1/win32s era, but it is small in modern
* contexts, so don't bother.
*/
}
int
BIO_socket_nbio(int s, int mode)
{
u_long value = mode;
return ioctlsocket(s, FIONBIO, &value) != SOCKET_ERROR;
}

520
externals/libressl/crypto/bio/bf_buff.c vendored Executable file
View File

@@ -0,0 +1,520 @@
/* $OpenBSD: bf_buff.c,v 1.25 2018/05/01 13:29:09 tb Exp $ */
/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
* All rights reserved.
*
* This package is an SSL implementation written
* by Eric Young (eay@cryptsoft.com).
* The implementation was written so as to conform with Netscapes SSL.
*
* This library is free for commercial and non-commercial use as long as
* the following conditions are aheared to. The following conditions
* apply to all code found in this distribution, be it the RC4, RSA,
* lhash, DES, etc., code; not just the SSL code. The SSL documentation
* included with this distribution is covered by the same copyright terms
* except that the holder is Tim Hudson (tjh@cryptsoft.com).
*
* Copyright remains Eric Young's, and as such any Copyright notices in
* the code are not to be removed.
* If this package is used in a product, Eric Young should be given attribution
* as the author of the parts of the library used.
* This can be in the form of a textual message at program startup or
* in documentation (online or textual) provided with the package.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* "This product includes cryptographic software written by
* Eric Young (eay@cryptsoft.com)"
* The word 'cryptographic' can be left out if the rouines from the library
* being used are not cryptographic related :-).
* 4. If you include any Windows specific code (or a derivative thereof) from
* the apps directory (application code) you must include an acknowledgement:
* "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
*
* THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* The licence and distribution terms for any publically available version or
* derivative of this code cannot be changed. i.e. this code cannot simply be
* copied and put under another distribution licence
* [including the GNU Public Licence.]
*/
#include <errno.h>
#include <stdio.h>
#include <string.h>
#include <openssl/bio.h>
#include <openssl/err.h>
static int buffer_write(BIO *h, const char *buf, int num);
static int buffer_read(BIO *h, char *buf, int size);
static int buffer_puts(BIO *h, const char *str);
static int buffer_gets(BIO *h, char *str, int size);
static long buffer_ctrl(BIO *h, int cmd, long arg1, void *arg2);
static int buffer_new(BIO *h);
static int buffer_free(BIO *data);
static long buffer_callback_ctrl(BIO *h, int cmd, bio_info_cb *fp);
#define DEFAULT_BUFFER_SIZE 4096
static const BIO_METHOD methods_buffer = {
.type = BIO_TYPE_BUFFER,
.name = "buffer",
.bwrite = buffer_write,
.bread = buffer_read,
.bputs = buffer_puts,
.bgets = buffer_gets,
.ctrl = buffer_ctrl,
.create = buffer_new,
.destroy = buffer_free,
.callback_ctrl = buffer_callback_ctrl
};
const BIO_METHOD *
BIO_f_buffer(void)
{
return (&methods_buffer);
}
static int
buffer_new(BIO *bi)
{
BIO_F_BUFFER_CTX *ctx;
ctx = malloc(sizeof(BIO_F_BUFFER_CTX));
if (ctx == NULL)
return (0);
ctx->ibuf = malloc(DEFAULT_BUFFER_SIZE);
if (ctx->ibuf == NULL) {
free(ctx);
return (0);
}
ctx->obuf = malloc(DEFAULT_BUFFER_SIZE);
if (ctx->obuf == NULL) {
free(ctx->ibuf);
free(ctx);
return (0);
}
ctx->ibuf_size = DEFAULT_BUFFER_SIZE;
ctx->obuf_size = DEFAULT_BUFFER_SIZE;
ctx->ibuf_len = 0;
ctx->ibuf_off = 0;
ctx->obuf_len = 0;
ctx->obuf_off = 0;
bi->init = 1;
bi->ptr = (char *)ctx;
bi->flags = 0;
return (1);
}
static int
buffer_free(BIO *a)
{
BIO_F_BUFFER_CTX *b;
if (a == NULL)
return (0);
b = (BIO_F_BUFFER_CTX *)a->ptr;
free(b->ibuf);
free(b->obuf);
free(a->ptr);
a->ptr = NULL;
a->init = 0;
a->flags = 0;
return (1);
}
static int
buffer_read(BIO *b, char *out, int outl)
{
int i, num = 0;
BIO_F_BUFFER_CTX *ctx;
if (out == NULL)
return (0);
ctx = (BIO_F_BUFFER_CTX *)b->ptr;
if ((ctx == NULL) || (b->next_bio == NULL))
return (0);
num = 0;
BIO_clear_retry_flags(b);
start:
i = ctx->ibuf_len;
/* If there is stuff left over, grab it */
if (i != 0) {
if (i > outl)
i = outl;
memcpy(out, &(ctx->ibuf[ctx->ibuf_off]), i);
ctx->ibuf_off += i;
ctx->ibuf_len -= i;
num += i;
if (outl == i)
return (num);
outl -= i;
out += i;
}
/* We may have done a partial read. try to do more.
* We have nothing in the buffer.
* If we get an error and have read some data, just return it
* and let them retry to get the error again.
* copy direct to parent address space */
if (outl > ctx->ibuf_size) {
for (;;) {
i = BIO_read(b->next_bio, out, outl);
if (i <= 0) {
BIO_copy_next_retry(b);
if (i < 0)
return ((num > 0) ? num : i);
if (i == 0)
return (num);
}
num += i;
if (outl == i)
return (num);
out += i;
outl -= i;
}
}
/* else */
/* we are going to be doing some buffering */
i = BIO_read(b->next_bio, ctx->ibuf, ctx->ibuf_size);
if (i <= 0) {
BIO_copy_next_retry(b);
if (i < 0)
return ((num > 0) ? num : i);
if (i == 0)
return (num);
}
ctx->ibuf_off = 0;
ctx->ibuf_len = i;
/* Lets re-read using ourselves :-) */
goto start;
}
static int
buffer_write(BIO *b, const char *in, int inl)
{
int i, num = 0;
BIO_F_BUFFER_CTX *ctx;
if ((in == NULL) || (inl <= 0))
return (0);
ctx = (BIO_F_BUFFER_CTX *)b->ptr;
if ((ctx == NULL) || (b->next_bio == NULL))
return (0);
BIO_clear_retry_flags(b);
start:
i = ctx->obuf_size - (ctx->obuf_len + ctx->obuf_off);
/* add to buffer and return */
if (i >= inl) {
memcpy(&(ctx->obuf[ctx->obuf_off + ctx->obuf_len]), in, inl);
ctx->obuf_len += inl;
return (num + inl);
}
/* else */
/* stuff already in buffer, so add to it first, then flush */
if (ctx->obuf_len != 0) {
if (i > 0) /* lets fill it up if we can */
{
memcpy(&(ctx->obuf[ctx->obuf_off + ctx->obuf_len]), in, i);
in += i;
inl -= i;
num += i;
ctx->obuf_len += i;
}
/* we now have a full buffer needing flushing */
for (;;) {
i = BIO_write(b->next_bio, &(ctx->obuf[ctx->obuf_off]),
ctx->obuf_len);
if (i <= 0) {
BIO_copy_next_retry(b);
if (i < 0)
return ((num > 0) ? num : i);
if (i == 0)
return (num);
}
ctx->obuf_off += i;
ctx->obuf_len -= i;
if (ctx->obuf_len == 0)
break;
}
}
/* we only get here if the buffer has been flushed and we
* still have stuff to write */
ctx->obuf_off = 0;
/* we now have inl bytes to write */
while (inl >= ctx->obuf_size) {
i = BIO_write(b->next_bio, in, inl);
if (i <= 0) {
BIO_copy_next_retry(b);
if (i < 0)
return ((num > 0) ? num : i);
if (i == 0)
return (num);
}
num += i;
in += i;
inl -= i;
if (inl == 0)
return (num);
}
/* copy the rest into the buffer since we have only a small
* amount left */
goto start;
}
static long
buffer_ctrl(BIO *b, int cmd, long num, void *ptr)
{
BIO *dbio;
BIO_F_BUFFER_CTX *ctx;
long ret = 1;
char *p1, *p2;
int r, i, *ip;
int ibs, obs;
ctx = (BIO_F_BUFFER_CTX *)b->ptr;
switch (cmd) {
case BIO_CTRL_RESET:
ctx->ibuf_off = 0;
ctx->ibuf_len = 0;
ctx->obuf_off = 0;
ctx->obuf_len = 0;
if (b->next_bio == NULL)
return (0);
ret = BIO_ctrl(b->next_bio, cmd, num, ptr);
break;
case BIO_CTRL_INFO:
ret = (long)ctx->obuf_len;
break;
case BIO_C_GET_BUFF_NUM_LINES:
ret = 0;
p1 = ctx->ibuf;
for (i = 0; i < ctx->ibuf_len; i++) {
if (p1[ctx->ibuf_off + i] == '\n')
ret++;
}
break;
case BIO_CTRL_WPENDING:
ret = (long)ctx->obuf_len;
if (ret == 0) {
if (b->next_bio == NULL)
return (0);
ret = BIO_ctrl(b->next_bio, cmd, num, ptr);
}
break;
case BIO_CTRL_PENDING:
ret = (long)ctx->ibuf_len;
if (ret == 0) {
if (b->next_bio == NULL)
return (0);
ret = BIO_ctrl(b->next_bio, cmd, num, ptr);
}
break;
case BIO_C_SET_BUFF_READ_DATA:
if (num > ctx->ibuf_size) {
p1 = malloc(num);
if (p1 == NULL)
goto malloc_error;
free(ctx->ibuf);
ctx->ibuf = p1;
}
ctx->ibuf_off = 0;
ctx->ibuf_len = (int)num;
memcpy(ctx->ibuf, ptr, num);
ret = 1;
break;
case BIO_C_SET_BUFF_SIZE:
if (ptr != NULL) {
ip = (int *)ptr;
if (*ip == 0) {
ibs = (int)num;
obs = ctx->obuf_size;
}
else /* if (*ip == 1) */
{
ibs = ctx->ibuf_size;
obs = (int)num;
}
} else {
ibs = (int)num;
obs = (int)num;
}
p1 = ctx->ibuf;
p2 = ctx->obuf;
if ((ibs > DEFAULT_BUFFER_SIZE) && (ibs != ctx->ibuf_size)) {
p1 = malloc(num);
if (p1 == NULL)
goto malloc_error;
}
if ((obs > DEFAULT_BUFFER_SIZE) && (obs != ctx->obuf_size)) {
p2 = malloc(num);
if (p2 == NULL) {
if (p1 != ctx->ibuf)
free(p1);
goto malloc_error;
}
}
if (ctx->ibuf != p1) {
free(ctx->ibuf);
ctx->ibuf = p1;
ctx->ibuf_off = 0;
ctx->ibuf_len = 0;
ctx->ibuf_size = ibs;
}
if (ctx->obuf != p2) {
free(ctx->obuf);
ctx->obuf = p2;
ctx->obuf_off = 0;
ctx->obuf_len = 0;
ctx->obuf_size = obs;
}
break;
case BIO_C_DO_STATE_MACHINE:
if (b->next_bio == NULL)
return (0);
BIO_clear_retry_flags(b);
ret = BIO_ctrl(b->next_bio, cmd, num, ptr);
BIO_copy_next_retry(b);
break;
case BIO_CTRL_FLUSH:
if (b->next_bio == NULL)
return (0);
if (ctx->obuf_len <= 0) {
ret = BIO_ctrl(b->next_bio, cmd, num, ptr);
break;
}
for (;;) {
BIO_clear_retry_flags(b);
if (ctx->obuf_len > 0) {
r = BIO_write(b->next_bio,
&(ctx->obuf[ctx->obuf_off]),
ctx->obuf_len);
BIO_copy_next_retry(b);
if (r <= 0)
return ((long)r);
ctx->obuf_off += r;
ctx->obuf_len -= r;
} else {
ctx->obuf_len = 0;
ctx->obuf_off = 0;
break;
}
}
ret = BIO_ctrl(b->next_bio, cmd, num, ptr);
break;
case BIO_CTRL_DUP:
dbio = (BIO *)ptr;
if (!BIO_set_read_buffer_size(dbio, ctx->ibuf_size) ||
!BIO_set_write_buffer_size(dbio, ctx->obuf_size))
ret = 0;
break;
default:
if (b->next_bio == NULL)
return (0);
ret = BIO_ctrl(b->next_bio, cmd, num, ptr);
break;
}
return (ret);
malloc_error:
BIOerror(ERR_R_MALLOC_FAILURE);
return (0);
}
static long
buffer_callback_ctrl(BIO *b, int cmd, bio_info_cb *fp)
{
long ret = 1;
if (b->next_bio == NULL)
return (0);
switch (cmd) {
default:
ret = BIO_callback_ctrl(b->next_bio, cmd, fp);
break;
}
return (ret);
}
static int
buffer_gets(BIO *b, char *buf, int size)
{
BIO_F_BUFFER_CTX *ctx;
int num = 0, i, flag;
char *p;
ctx = (BIO_F_BUFFER_CTX *)b->ptr;
size--; /* reserve space for a '\0' */
BIO_clear_retry_flags(b);
for (;;) {
if (ctx->ibuf_len > 0) {
p = &(ctx->ibuf[ctx->ibuf_off]);
flag = 0;
for (i = 0; (i < ctx->ibuf_len) && (i < size); i++) {
*(buf++) = p[i];
if (p[i] == '\n') {
flag = 1;
i++;
break;
}
}
num += i;
size -= i;
ctx->ibuf_len -= i;
ctx->ibuf_off += i;
if (flag || size == 0) {
*buf = '\0';
return (num);
}
}
else /* read another chunk */
{
i = BIO_read(b->next_bio, ctx->ibuf, ctx->ibuf_size);
if (i <= 0) {
BIO_copy_next_retry(b);
*buf = '\0';
if (i < 0)
return ((num > 0) ? num : i);
if (i == 0)
return (num);
}
ctx->ibuf_len = i;
ctx->ibuf_off = 0;
}
}
}
static int
buffer_puts(BIO *b, const char *str)
{
return (buffer_write(b, str, strlen(str)));
}

252
externals/libressl/crypto/bio/bf_nbio.c vendored Executable file
View File

@@ -0,0 +1,252 @@
/* $OpenBSD: bf_nbio.c,v 1.20 2018/05/01 13:29:09 tb Exp $ */
/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
* All rights reserved.
*
* This package is an SSL implementation written
* by Eric Young (eay@cryptsoft.com).
* The implementation was written so as to conform with Netscapes SSL.
*
* This library is free for commercial and non-commercial use as long as
* the following conditions are aheared to. The following conditions
* apply to all code found in this distribution, be it the RC4, RSA,
* lhash, DES, etc., code; not just the SSL code. The SSL documentation
* included with this distribution is covered by the same copyright terms
* except that the holder is Tim Hudson (tjh@cryptsoft.com).
*
* Copyright remains Eric Young's, and as such any Copyright notices in
* the code are not to be removed.
* If this package is used in a product, Eric Young should be given attribution
* as the author of the parts of the library used.
* This can be in the form of a textual message at program startup or
* in documentation (online or textual) provided with the package.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* "This product includes cryptographic software written by
* Eric Young (eay@cryptsoft.com)"
* The word 'cryptographic' can be left out if the rouines from the library
* being used are not cryptographic related :-).
* 4. If you include any Windows specific code (or a derivative thereof) from
* the apps directory (application code) you must include an acknowledgement:
* "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
*
* THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* The licence and distribution terms for any publically available version or
* derivative of this code cannot be changed. i.e. this code cannot simply be
* copied and put under another distribution licence
* [including the GNU Public Licence.]
*/
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <openssl/bio.h>
/* BIO_put and BIO_get both add to the digest,
* BIO_gets returns the digest */
static int nbiof_write(BIO *h, const char *buf, int num);
static int nbiof_read(BIO *h, char *buf, int size);
static int nbiof_puts(BIO *h, const char *str);
static int nbiof_gets(BIO *h, char *str, int size);
static long nbiof_ctrl(BIO *h, int cmd, long arg1, void *arg2);
static int nbiof_new(BIO *h);
static int nbiof_free(BIO *data);
static long nbiof_callback_ctrl(BIO *h, int cmd, bio_info_cb *fp);
typedef struct nbio_test_st {
/* only set if we sent a 'should retry' error */
int lrn;
int lwn;
} NBIO_TEST;
static const BIO_METHOD methods_nbiof = {
.type = BIO_TYPE_NBIO_TEST,
.name = "non-blocking IO test filter",
.bwrite = nbiof_write,
.bread = nbiof_read,
.bputs = nbiof_puts,
.bgets = nbiof_gets,
.ctrl = nbiof_ctrl,
.create = nbiof_new,
.destroy = nbiof_free,
.callback_ctrl = nbiof_callback_ctrl
};
const BIO_METHOD *
BIO_f_nbio_test(void)
{
return (&methods_nbiof);
}
static int
nbiof_new(BIO *bi)
{
NBIO_TEST *nt;
if (!(nt = malloc(sizeof(NBIO_TEST))))
return (0);
nt->lrn = -1;
nt->lwn = -1;
bi->ptr = (char *)nt;
bi->init = 1;
bi->flags = 0;
return (1);
}
static int
nbiof_free(BIO *a)
{
if (a == NULL)
return (0);
free(a->ptr);
a->ptr = NULL;
a->init = 0;
a->flags = 0;
return (1);
}
static int
nbiof_read(BIO *b, char *out, int outl)
{
int ret = 0;
int num;
unsigned char n;
if (out == NULL)
return (0);
if (b->next_bio == NULL)
return (0);
BIO_clear_retry_flags(b);
arc4random_buf(&n, 1);
num = (n & 0x07);
if (outl > num)
outl = num;
if (num == 0) {
ret = -1;
BIO_set_retry_read(b);
} else {
ret = BIO_read(b->next_bio, out, outl);
if (ret < 0)
BIO_copy_next_retry(b);
}
return (ret);
}
static int
nbiof_write(BIO *b, const char *in, int inl)
{
NBIO_TEST *nt;
int ret = 0;
int num;
unsigned char n;
if ((in == NULL) || (inl <= 0))
return (0);
if (b->next_bio == NULL)
return (0);
nt = (NBIO_TEST *)b->ptr;
BIO_clear_retry_flags(b);
if (nt->lwn > 0) {
num = nt->lwn;
nt->lwn = 0;
} else {
arc4random_buf(&n, 1);
num = (n&7);
}
if (inl > num)
inl = num;
if (num == 0) {
ret = -1;
BIO_set_retry_write(b);
} else {
ret = BIO_write(b->next_bio, in, inl);
if (ret < 0) {
BIO_copy_next_retry(b);
nt->lwn = inl;
}
}
return (ret);
}
static long
nbiof_ctrl(BIO *b, int cmd, long num, void *ptr)
{
long ret;
if (b->next_bio == NULL)
return (0);
switch (cmd) {
case BIO_C_DO_STATE_MACHINE:
BIO_clear_retry_flags(b);
ret = BIO_ctrl(b->next_bio, cmd, num, ptr);
BIO_copy_next_retry(b);
break;
case BIO_CTRL_DUP:
ret = 0L;
break;
default:
ret = BIO_ctrl(b->next_bio, cmd, num, ptr);
break;
}
return (ret);
}
static long
nbiof_callback_ctrl(BIO *b, int cmd, bio_info_cb *fp)
{
long ret = 1;
if (b->next_bio == NULL)
return (0);
switch (cmd) {
default:
ret = BIO_callback_ctrl(b->next_bio, cmd, fp);
break;
}
return (ret);
}
static int
nbiof_gets(BIO *bp, char *buf, int size)
{
if (bp->next_bio == NULL)
return (0);
return (BIO_gets(bp->next_bio, buf, size));
}
static int
nbiof_puts(BIO *bp, const char *str)
{
if (bp->next_bio == NULL)
return (0);
return (BIO_puts(bp->next_bio, str));
}

196
externals/libressl/crypto/bio/bf_null.c vendored Executable file
View File

@@ -0,0 +1,196 @@
/* $OpenBSD: bf_null.c,v 1.12 2018/05/01 13:29:09 tb Exp $ */
/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
* All rights reserved.
*
* This package is an SSL implementation written
* by Eric Young (eay@cryptsoft.com).
* The implementation was written so as to conform with Netscapes SSL.
*
* This library is free for commercial and non-commercial use as long as
* the following conditions are aheared to. The following conditions
* apply to all code found in this distribution, be it the RC4, RSA,
* lhash, DES, etc., code; not just the SSL code. The SSL documentation
* included with this distribution is covered by the same copyright terms
* except that the holder is Tim Hudson (tjh@cryptsoft.com).
*
* Copyright remains Eric Young's, and as such any Copyright notices in
* the code are not to be removed.
* If this package is used in a product, Eric Young should be given attribution
* as the author of the parts of the library used.
* This can be in the form of a textual message at program startup or
* in documentation (online or textual) provided with the package.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* "This product includes cryptographic software written by
* Eric Young (eay@cryptsoft.com)"
* The word 'cryptographic' can be left out if the rouines from the library
* being used are not cryptographic related :-).
* 4. If you include any Windows specific code (or a derivative thereof) from
* the apps directory (application code) you must include an acknowledgement:
* "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
*
* THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* The licence and distribution terms for any publically available version or
* derivative of this code cannot be changed. i.e. this code cannot simply be
* copied and put under another distribution licence
* [including the GNU Public Licence.]
*/
#include <errno.h>
#include <stdio.h>
#include <openssl/bio.h>
/* BIO_put and BIO_get both add to the digest,
* BIO_gets returns the digest */
static int nullf_write(BIO *h, const char *buf, int num);
static int nullf_read(BIO *h, char *buf, int size);
static int nullf_puts(BIO *h, const char *str);
static int nullf_gets(BIO *h, char *str, int size);
static long nullf_ctrl(BIO *h, int cmd, long arg1, void *arg2);
static int nullf_new(BIO *h);
static int nullf_free(BIO *data);
static long nullf_callback_ctrl(BIO *h, int cmd, bio_info_cb *fp);
static const BIO_METHOD methods_nullf = {
.type = BIO_TYPE_NULL_FILTER,
.name = "NULL filter",
.bwrite = nullf_write,
.bread = nullf_read,
.bputs = nullf_puts,
.bgets = nullf_gets,
.ctrl = nullf_ctrl,
.create = nullf_new,
.destroy = nullf_free,
.callback_ctrl = nullf_callback_ctrl
};
const BIO_METHOD *
BIO_f_null(void)
{
return (&methods_nullf);
}
static int
nullf_new(BIO *bi)
{
bi->init = 1;
bi->ptr = NULL;
bi->flags = 0;
return (1);
}
static int
nullf_free(BIO *a)
{
if (a == NULL)
return (0);
/* a->ptr=NULL;
a->init=0;
a->flags=0;*/
return (1);
}
static int
nullf_read(BIO *b, char *out, int outl)
{
int ret = 0;
if (out == NULL)
return (0);
if (b->next_bio == NULL)
return (0);
ret = BIO_read(b->next_bio, out, outl);
BIO_clear_retry_flags(b);
BIO_copy_next_retry(b);
return (ret);
}
static int
nullf_write(BIO *b, const char *in, int inl)
{
int ret = 0;
if ((in == NULL) || (inl <= 0))
return (0);
if (b->next_bio == NULL)
return (0);
ret = BIO_write(b->next_bio, in, inl);
BIO_clear_retry_flags(b);
BIO_copy_next_retry(b);
return (ret);
}
static long
nullf_ctrl(BIO *b, int cmd, long num, void *ptr)
{
long ret;
if (b->next_bio == NULL)
return (0);
switch (cmd) {
case BIO_C_DO_STATE_MACHINE:
BIO_clear_retry_flags(b);
ret = BIO_ctrl(b->next_bio, cmd, num, ptr);
BIO_copy_next_retry(b);
break;
case BIO_CTRL_DUP:
ret = 0L;
break;
default:
ret = BIO_ctrl(b->next_bio, cmd, num, ptr);
}
return (ret);
}
static long
nullf_callback_ctrl(BIO *b, int cmd, bio_info_cb *fp)
{
long ret = 1;
if (b->next_bio == NULL)
return (0);
switch (cmd) {
default:
ret = BIO_callback_ctrl(b->next_bio, cmd, fp);
break;
}
return (ret);
}
static int
nullf_gets(BIO *bp, char *buf, int size)
{
if (bp->next_bio == NULL)
return (0);
return (BIO_gets(bp->next_bio, buf, size));
}
static int
nullf_puts(BIO *bp, const char *str)
{
if (bp->next_bio == NULL)
return (0);
return (BIO_puts(bp->next_bio, str));
}

145
externals/libressl/crypto/bio/bio_cb.c vendored Executable file
View File

@@ -0,0 +1,145 @@
/* $OpenBSD: bio_cb.c,v 1.16 2014/12/08 03:54:19 bcook Exp $ */
/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
* All rights reserved.
*
* This package is an SSL implementation written
* by Eric Young (eay@cryptsoft.com).
* The implementation was written so as to conform with Netscapes SSL.
*
* This library is free for commercial and non-commercial use as long as
* the following conditions are aheared to. The following conditions
* apply to all code found in this distribution, be it the RC4, RSA,
* lhash, DES, etc., code; not just the SSL code. The SSL documentation
* included with this distribution is covered by the same copyright terms
* except that the holder is Tim Hudson (tjh@cryptsoft.com).
*
* Copyright remains Eric Young's, and as such any Copyright notices in
* the code are not to be removed.
* If this package is used in a product, Eric Young should be given attribution
* as the author of the parts of the library used.
* This can be in the form of a textual message at program startup or
* in documentation (online or textual) provided with the package.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* "This product includes cryptographic software written by
* Eric Young (eay@cryptsoft.com)"
* The word 'cryptographic' can be left out if the rouines from the library
* being used are not cryptographic related :-).
* 4. If you include any Windows specific code (or a derivative thereof) from
* the apps directory (application code) you must include an acknowledgement:
* "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
*
* THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* The licence and distribution terms for any publically available version or
* derivative of this code cannot be changed. i.e. this code cannot simply be
* copied and put under another distribution licence
* [including the GNU Public Licence.]
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <openssl/err.h>
#include <openssl/bio.h>
long
BIO_debug_callback(BIO *bio, int cmd, const char *argp, int argi, long argl,
long ret)
{
BIO *b;
char buf[256];
char *p;
long r = 1;
size_t p_maxlen;
if (BIO_CB_RETURN & cmd)
r = ret;
snprintf(buf, sizeof buf, "BIO[%p]:", bio);
p = &(buf[14]);
p_maxlen = sizeof buf - 14;
switch (cmd) {
case BIO_CB_FREE:
snprintf(p, p_maxlen, "Free - %s\n", bio->method->name);
break;
case BIO_CB_READ:
if (bio->method->type & BIO_TYPE_DESCRIPTOR)
snprintf(p, p_maxlen,
"read(%d,%lu) - %s fd=%d\n",
bio->num, (unsigned long)argi,
bio->method->name, bio->num);
else
snprintf(p, p_maxlen, "read(%d,%lu) - %s\n",
bio->num, (unsigned long)argi, bio->method->name);
break;
case BIO_CB_WRITE:
if (bio->method->type & BIO_TYPE_DESCRIPTOR)
snprintf(p, p_maxlen,
"write(%d,%lu) - %s fd=%d\n",
bio->num, (unsigned long)argi,
bio->method->name, bio->num);
else
snprintf(p, p_maxlen, "write(%d,%lu) - %s\n",
bio->num, (unsigned long)argi, bio->method->name);
break;
case BIO_CB_PUTS:
snprintf(p, p_maxlen,
"puts() - %s\n", bio->method->name);
break;
case BIO_CB_GETS:
snprintf(p, p_maxlen, "gets(%lu) - %s\n",
(unsigned long)argi, bio->method->name);
break;
case BIO_CB_CTRL:
snprintf(p, p_maxlen, "ctrl(%lu) - %s\n",
(unsigned long)argi, bio->method->name);
break;
case BIO_CB_RETURN|BIO_CB_READ:
snprintf(p, p_maxlen, "read return %ld\n", ret);
break;
case BIO_CB_RETURN|BIO_CB_WRITE:
snprintf(p, p_maxlen, "write return %ld\n", ret);
break;
case BIO_CB_RETURN|BIO_CB_GETS:
snprintf(p, p_maxlen, "gets return %ld\n", ret);
break;
case BIO_CB_RETURN|BIO_CB_PUTS:
snprintf(p, p_maxlen, "puts return %ld\n", ret);
break;
case BIO_CB_RETURN|BIO_CB_CTRL:
snprintf(p, p_maxlen, "ctrl return %ld\n", ret);
break;
default:
snprintf(p, p_maxlen,
"bio callback - unknown type (%d)\n", cmd);
break;
}
b = (BIO *)bio->cb_arg;
if (b != NULL)
BIO_write(b, buf, strlen(buf));
else
fputs(buf, stderr);
return (r);
}

124
externals/libressl/crypto/bio/bio_err.c vendored Executable file
View File

@@ -0,0 +1,124 @@
/* $OpenBSD: bio_err.c,v 1.17 2017/01/29 17:49:22 beck Exp $ */
/* ====================================================================
* Copyright (c) 1999-2011 The OpenSSL Project. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. All advertising materials mentioning features or use of this
* software must display the following acknowledgment:
* "This product includes software developed by the OpenSSL Project
* for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
*
* 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
* endorse or promote products derived from this software without
* prior written permission. For written permission, please contact
* openssl-core@OpenSSL.org.
*
* 5. Products derived from this software may not be called "OpenSSL"
* nor may "OpenSSL" appear in their names without prior written
* permission of the OpenSSL Project.
*
* 6. Redistributions of any form whatsoever must retain the following
* acknowledgment:
* "This product includes software developed by the OpenSSL Project
* for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
*
* THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
* EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
* OF THE POSSIBILITY OF SUCH DAMAGE.
* ====================================================================
*
* This product includes cryptographic software written by Eric Young
* (eay@cryptsoft.com). This product includes software written by Tim
* Hudson (tjh@cryptsoft.com).
*
*/
/* NOTE: this file was auto generated by the mkerr.pl script: any changes
* made to it will be overwritten when the script next updates this file,
* only reason strings will be preserved.
*/
#include <stdio.h>
#include <openssl/opensslconf.h>
#include <openssl/err.h>
#include <openssl/bio.h>
/* BEGIN ERROR CODES */
#ifndef OPENSSL_NO_ERR
#define ERR_FUNC(func) ERR_PACK(ERR_LIB_BIO,func,0)
#define ERR_REASON(reason) ERR_PACK(ERR_LIB_BIO,0,reason)
static ERR_STRING_DATA BIO_str_functs[] = {
{ERR_FUNC(0xfff), "CRYPTO_internal"},
{0, NULL}
};
static ERR_STRING_DATA BIO_str_reasons[] = {
{ERR_REASON(BIO_R_ACCEPT_ERROR) , "accept error"},
{ERR_REASON(BIO_R_BAD_FOPEN_MODE) , "bad fopen mode"},
{ERR_REASON(BIO_R_BAD_HOSTNAME_LOOKUP) , "bad hostname lookup"},
{ERR_REASON(BIO_R_BROKEN_PIPE) , "broken pipe"},
{ERR_REASON(BIO_R_CONNECT_ERROR) , "connect error"},
{ERR_REASON(BIO_R_EOF_ON_MEMORY_BIO) , "EOF on memory BIO"},
{ERR_REASON(BIO_R_ERROR_SETTING_NBIO) , "error setting nbio"},
{ERR_REASON(BIO_R_ERROR_SETTING_NBIO_ON_ACCEPTED_SOCKET), "error setting nbio on accepted socket"},
{ERR_REASON(BIO_R_ERROR_SETTING_NBIO_ON_ACCEPT_SOCKET), "error setting nbio on accept socket"},
{ERR_REASON(BIO_R_GETHOSTBYNAME_ADDR_IS_NOT_AF_INET), "gethostbyname addr is not af inet"},
{ERR_REASON(BIO_R_INVALID_ARGUMENT) , "invalid argument"},
{ERR_REASON(BIO_R_INVALID_IP_ADDRESS) , "invalid ip address"},
{ERR_REASON(BIO_R_INVALID_PORT_NUMBER) , "invalid port number"},
{ERR_REASON(BIO_R_IN_USE) , "in use"},
{ERR_REASON(BIO_R_KEEPALIVE) , "keepalive"},
{ERR_REASON(BIO_R_NBIO_CONNECT_ERROR) , "nbio connect error"},
{ERR_REASON(BIO_R_NO_ACCEPT_PORT_SPECIFIED), "no accept port specified"},
{ERR_REASON(BIO_R_NO_HOSTNAME_SPECIFIED) , "no hostname specified"},
{ERR_REASON(BIO_R_NO_PORT_DEFINED) , "no port defined"},
{ERR_REASON(BIO_R_NO_PORT_SPECIFIED) , "no port specified"},
{ERR_REASON(BIO_R_NO_SUCH_FILE) , "no such file"},
{ERR_REASON(BIO_R_NULL_PARAMETER) , "null parameter"},
{ERR_REASON(BIO_R_TAG_MISMATCH) , "tag mismatch"},
{ERR_REASON(BIO_R_UNABLE_TO_BIND_SOCKET) , "unable to bind socket"},
{ERR_REASON(BIO_R_UNABLE_TO_CREATE_SOCKET), "unable to create socket"},
{ERR_REASON(BIO_R_UNABLE_TO_LISTEN_SOCKET), "unable to listen socket"},
{ERR_REASON(BIO_R_UNINITIALIZED) , "uninitialized"},
{ERR_REASON(BIO_R_UNSUPPORTED_METHOD) , "unsupported method"},
{ERR_REASON(BIO_R_WRITE_TO_READ_ONLY_BIO), "write to read only BIO"},
{ERR_REASON(BIO_R_WSASTARTUP) , "WSAStartup"},
{0, NULL}
};
#endif
void
ERR_load_BIO_strings(void)
{
#ifndef OPENSSL_NO_ERR
if (ERR_func_error_string(BIO_str_functs[0].error) == NULL) {
ERR_load_strings(0, BIO_str_functs);
ERR_load_strings(0, BIO_str_reasons);
}
#endif
}

685
externals/libressl/crypto/bio/bio_lib.c vendored Executable file
View File

@@ -0,0 +1,685 @@
/* $OpenBSD: bio_lib.c,v 1.29 2019/04/14 17:39:03 jsing Exp $ */
/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
* All rights reserved.
*
* This package is an SSL implementation written
* by Eric Young (eay@cryptsoft.com).
* The implementation was written so as to conform with Netscapes SSL.
*
* This library is free for commercial and non-commercial use as long as
* the following conditions are aheared to. The following conditions
* apply to all code found in this distribution, be it the RC4, RSA,
* lhash, DES, etc., code; not just the SSL code. The SSL documentation
* included with this distribution is covered by the same copyright terms
* except that the holder is Tim Hudson (tjh@cryptsoft.com).
*
* Copyright remains Eric Young's, and as such any Copyright notices in
* the code are not to be removed.
* If this package is used in a product, Eric Young should be given attribution
* as the author of the parts of the library used.
* This can be in the form of a textual message at program startup or
* in documentation (online or textual) provided with the package.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* "This product includes cryptographic software written by
* Eric Young (eay@cryptsoft.com)"
* The word 'cryptographic' can be left out if the rouines from the library
* being used are not cryptographic related :-).
* 4. If you include any Windows specific code (or a derivative thereof) from
* the apps directory (application code) you must include an acknowledgement:
* "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
*
* THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* The licence and distribution terms for any publically available version or
* derivative of this code cannot be changed. i.e. this code cannot simply be
* copied and put under another distribution licence
* [including the GNU Public Licence.]
*/
#include <errno.h>
#include <stdio.h>
#include <openssl/bio.h>
#include <openssl/crypto.h>
#include <openssl/err.h>
#include <openssl/stack.h>
int
BIO_get_new_index(void)
{
static int bio_type_index = BIO_TYPE_START;
int index;
/* The index will collide with the BIO flag bits if it exceeds 255. */
index = CRYPTO_add(&bio_type_index, 1, CRYPTO_LOCK_BIO);
if (index > 255)
return -1;
return index;
}
BIO *
BIO_new(const BIO_METHOD *method)
{
BIO *ret = NULL;
ret = malloc(sizeof(BIO));
if (ret == NULL) {
BIOerror(ERR_R_MALLOC_FAILURE);
return (NULL);
}
if (!BIO_set(ret, method)) {
free(ret);
ret = NULL;
}
return (ret);
}
int
BIO_set(BIO *bio, const BIO_METHOD *method)
{
bio->method = method;
bio->callback = NULL;
bio->cb_arg = NULL;
bio->init = 0;
bio->shutdown = 1;
bio->flags = 0;
bio->retry_reason = 0;
bio->num = 0;
bio->ptr = NULL;
bio->prev_bio = NULL;
bio->next_bio = NULL;
bio->references = 1;
bio->num_read = 0L;
bio->num_write = 0L;
CRYPTO_new_ex_data(CRYPTO_EX_INDEX_BIO, bio, &bio->ex_data);
if (method->create != NULL)
if (!method->create(bio)) {
CRYPTO_free_ex_data(CRYPTO_EX_INDEX_BIO, bio,
&bio->ex_data);
return (0);
}
return (1);
}
int
BIO_free(BIO *a)
{
int i;
if (a == NULL)
return (0);
i = CRYPTO_add(&a->references, -1, CRYPTO_LOCK_BIO);
if (i > 0)
return (1);
if ((a->callback != NULL) &&
((i = (int)a->callback(a, BIO_CB_FREE, NULL, 0, 0L, 1L)) <= 0))
return (i);
CRYPTO_free_ex_data(CRYPTO_EX_INDEX_BIO, a, &a->ex_data);
if (a->method != NULL && a->method->destroy != NULL)
a->method->destroy(a);
free(a);
return (1);
}
void
BIO_vfree(BIO *a)
{
BIO_free(a);
}
int
BIO_up_ref(BIO *bio)
{
int refs = CRYPTO_add(&bio->references, 1, CRYPTO_LOCK_BIO);
return (refs > 1) ? 1 : 0;
}
void *
BIO_get_data(BIO *a)
{
return (a->ptr);
}
void
BIO_set_data(BIO *a, void *ptr)
{
a->ptr = ptr;
}
void
BIO_set_init(BIO *a, int init)
{
a->init = init;
}
int
BIO_get_shutdown(BIO *a)
{
return (a->shutdown);
}
void
BIO_set_shutdown(BIO *a, int shut)
{
a->shutdown = shut;
}
void
BIO_clear_flags(BIO *b, int flags)
{
b->flags &= ~flags;
}
int
BIO_test_flags(const BIO *b, int flags)
{
return (b->flags & flags);
}
void
BIO_set_flags(BIO *b, int flags)
{
b->flags |= flags;
}
long
(*BIO_get_callback(const BIO *b))(struct bio_st *, int, const char *, int,
long, long)
{
return b->callback;
}
void
BIO_set_callback(BIO *b, long (*cb)(struct bio_st *, int, const char *, int,
long, long))
{
b->callback = cb;
}
void
BIO_set_callback_arg(BIO *b, char *arg)
{
b->cb_arg = arg;
}
char *
BIO_get_callback_arg(const BIO *b)
{
return b->cb_arg;
}
const char *
BIO_method_name(const BIO *b)
{
return b->method->name;
}
int
BIO_method_type(const BIO *b)
{
return b->method->type;
}
int
BIO_read(BIO *b, void *out, int outl)
{
int i;
long (*cb)(BIO *, int, const char *, int, long, long);
if (b == NULL)
return (0);
if (out == NULL || outl <= 0)
return (0);
if (b->method == NULL || b->method->bread == NULL) {
BIOerror(BIO_R_UNSUPPORTED_METHOD);
return (-2);
}
cb = b->callback;
if ((cb != NULL) &&
((i = (int)cb(b, BIO_CB_READ, out, outl, 0L, 1L)) <= 0))
return (i);
if (!b->init) {
BIOerror(BIO_R_UNINITIALIZED);
return (-2);
}
i = b->method->bread(b, out, outl);
if (i > 0)
b->num_read += (unsigned long)i;
if (cb != NULL)
i = (int)cb(b, BIO_CB_READ|BIO_CB_RETURN, out, outl,
0L, (long)i);
return (i);
}
int
BIO_write(BIO *b, const void *in, int inl)
{
int i;
long (*cb)(BIO *, int, const char *, int, long, long);
if (b == NULL)
return (0);
if (in == NULL || inl <= 0)
return (0);
if (b->method == NULL || b->method->bwrite == NULL) {
BIOerror(BIO_R_UNSUPPORTED_METHOD);
return (-2);
}
cb = b->callback;
if ((cb != NULL) &&
((i = (int)cb(b, BIO_CB_WRITE, in, inl, 0L, 1L)) <= 0))
return (i);
if (!b->init) {
BIOerror(BIO_R_UNINITIALIZED);
return (-2);
}
i = b->method->bwrite(b, in, inl);
if (i > 0)
b->num_write += (unsigned long)i;
if (cb != NULL)
i = (int)cb(b, BIO_CB_WRITE|BIO_CB_RETURN, in, inl,
0L, (long)i);
return (i);
}
int
BIO_puts(BIO *b, const char *in)
{
int i;
long (*cb)(BIO *, int, const char *, int, long, long);
if ((b == NULL) || (b->method == NULL) || (b->method->bputs == NULL)) {
BIOerror(BIO_R_UNSUPPORTED_METHOD);
return (-2);
}
cb = b->callback;
if ((cb != NULL) &&
((i = (int)cb(b, BIO_CB_PUTS, in, 0, 0L, 1L)) <= 0))
return (i);
if (!b->init) {
BIOerror(BIO_R_UNINITIALIZED);
return (-2);
}
i = b->method->bputs(b, in);
if (i > 0)
b->num_write += (unsigned long)i;
if (cb != NULL)
i = (int)cb(b, BIO_CB_PUTS|BIO_CB_RETURN, in, 0, 0L, (long)i);
return (i);
}
int
BIO_gets(BIO *b, char *in, int inl)
{
int i;
long (*cb)(BIO *, int, const char *, int, long, long);
if ((b == NULL) || (b->method == NULL) || (b->method->bgets == NULL)) {
BIOerror(BIO_R_UNSUPPORTED_METHOD);
return (-2);
}
cb = b->callback;
if ((cb != NULL) &&
((i = (int)cb(b, BIO_CB_GETS, in, inl, 0L, 1L)) <= 0))
return (i);
if (!b->init) {
BIOerror(BIO_R_UNINITIALIZED);
return (-2);
}
i = b->method->bgets(b, in, inl);
if (cb != NULL)
i = (int)cb(b, BIO_CB_GETS|BIO_CB_RETURN, in, inl, 0L, (long)i);
return (i);
}
int
BIO_indent(BIO *b, int indent, int max)
{
if (indent < 0)
indent = 0;
if (indent > max)
indent = max;
while (indent--)
if (BIO_puts(b, " ") != 1)
return 0;
return 1;
}
long
BIO_int_ctrl(BIO *b, int cmd, long larg, int iarg)
{
int i;
i = iarg;
return (BIO_ctrl(b, cmd, larg, (char *)&i));
}
char *
BIO_ptr_ctrl(BIO *b, int cmd, long larg)
{
char *p = NULL;
if (BIO_ctrl(b, cmd, larg, (char *)&p) <= 0)
return (NULL);
else
return (p);
}
long
BIO_ctrl(BIO *b, int cmd, long larg, void *parg)
{
long ret;
long (*cb)(BIO *, int, const char *, int, long, long);
if (b == NULL)
return (0);
if ((b->method == NULL) || (b->method->ctrl == NULL)) {
BIOerror(BIO_R_UNSUPPORTED_METHOD);
return (-2);
}
cb = b->callback;
if ((cb != NULL) &&
((ret = cb(b, BIO_CB_CTRL, parg, cmd, larg, 1L)) <= 0))
return (ret);
ret = b->method->ctrl(b, cmd, larg, parg);
if (cb != NULL)
ret = cb(b, BIO_CB_CTRL|BIO_CB_RETURN, parg, cmd, larg, ret);
return (ret);
}
long
BIO_callback_ctrl(BIO *b, int cmd,
void (*fp)(struct bio_st *, int, const char *, int, long, long))
{
long ret;
long (*cb)(BIO *, int, const char *, int, long, long);
if (b == NULL)
return (0);
if ((b->method == NULL) || (b->method->callback_ctrl == NULL)) {
BIOerror(BIO_R_UNSUPPORTED_METHOD);
return (-2);
}
cb = b->callback;
if ((cb != NULL) &&
((ret = cb(b, BIO_CB_CTRL, (void *)&fp, cmd, 0, 1L)) <= 0))
return (ret);
ret = b->method->callback_ctrl(b, cmd, fp);
if (cb != NULL)
ret = cb(b, BIO_CB_CTRL|BIO_CB_RETURN, (void *)&fp, cmd, 0, ret);
return (ret);
}
/* It is unfortunate to duplicate in functions what the BIO_(w)pending macros
* do; but those macros have inappropriate return type, and for interfacing
* from other programming languages, C macros aren't much of a help anyway. */
size_t
BIO_ctrl_pending(BIO *bio)
{
return BIO_ctrl(bio, BIO_CTRL_PENDING, 0, NULL);
}
size_t
BIO_ctrl_wpending(BIO *bio)
{
return BIO_ctrl(bio, BIO_CTRL_WPENDING, 0, NULL);
}
/* put the 'bio' on the end of b's list of operators */
BIO *
BIO_push(BIO *b, BIO *bio)
{
BIO *lb;
if (b == NULL)
return (bio);
lb = b;
while (lb->next_bio != NULL)
lb = lb->next_bio;
lb->next_bio = bio;
if (bio != NULL)
bio->prev_bio = lb;
/* called to do internal processing */
BIO_ctrl(b, BIO_CTRL_PUSH, 0, lb);
return (b);
}
/* Remove the first and return the rest */
BIO *
BIO_pop(BIO *b)
{
BIO *ret;
if (b == NULL)
return (NULL);
ret = b->next_bio;
BIO_ctrl(b, BIO_CTRL_POP, 0, b);
if (b->prev_bio != NULL)
b->prev_bio->next_bio = b->next_bio;
if (b->next_bio != NULL)
b->next_bio->prev_bio = b->prev_bio;
b->next_bio = NULL;
b->prev_bio = NULL;
return (ret);
}
BIO *
BIO_get_retry_BIO(BIO *bio, int *reason)
{
BIO *b, *last;
b = last = bio;
for (;;) {
if (!BIO_should_retry(b))
break;
last = b;
b = b->next_bio;
if (b == NULL)
break;
}
if (reason != NULL)
*reason = last->retry_reason;
return (last);
}
int
BIO_get_retry_reason(BIO *bio)
{
return (bio->retry_reason);
}
BIO *
BIO_find_type(BIO *bio, int type)
{
int mt, mask;
if (!bio)
return NULL;
mask = type & 0xff;
do {
if (bio->method != NULL) {
mt = bio->method->type;
if (!mask) {
if (mt & type)
return (bio);
} else if (mt == type)
return (bio);
}
bio = bio->next_bio;
} while (bio != NULL);
return (NULL);
}
BIO *
BIO_next(BIO *b)
{
if (!b)
return NULL;
return b->next_bio;
}
void
BIO_free_all(BIO *bio)
{
BIO *b;
int ref;
while (bio != NULL) {
b = bio;
ref = b->references;
bio = bio->next_bio;
BIO_free(b);
/* Since ref count > 1, don't free anyone else. */
if (ref > 1)
break;
}
}
BIO *
BIO_dup_chain(BIO *in)
{
BIO *ret = NULL, *eoc = NULL, *bio, *new_bio;
for (bio = in; bio != NULL; bio = bio->next_bio) {
if ((new_bio = BIO_new(bio->method)) == NULL)
goto err;
new_bio->callback = bio->callback;
new_bio->cb_arg = bio->cb_arg;
new_bio->init = bio->init;
new_bio->shutdown = bio->shutdown;
new_bio->flags = bio->flags;
/* This will let SSL_s_sock() work with stdin/stdout */
new_bio->num = bio->num;
if (!BIO_dup_state(bio, (char *)new_bio)) {
BIO_free(new_bio);
goto err;
}
/* copy app data */
if (!CRYPTO_dup_ex_data(CRYPTO_EX_INDEX_BIO,
&new_bio->ex_data, &bio->ex_data))
goto err;
if (ret == NULL) {
eoc = new_bio;
ret = eoc;
} else {
BIO_push(eoc, new_bio);
eoc = new_bio;
}
}
return (ret);
err:
BIO_free(ret);
return (NULL);
}
void
BIO_copy_next_retry(BIO *b)
{
BIO_set_flags(b, BIO_get_retry_flags(b->next_bio));
b->retry_reason = b->next_bio->retry_reason;
}
int
BIO_get_ex_new_index(long argl, void *argp, CRYPTO_EX_new *new_func,
CRYPTO_EX_dup *dup_func, CRYPTO_EX_free *free_func)
{
return CRYPTO_get_ex_new_index(CRYPTO_EX_INDEX_BIO, argl, argp,
new_func, dup_func, free_func);
}
int
BIO_set_ex_data(BIO *bio, int idx, void *data)
{
return (CRYPTO_set_ex_data(&(bio->ex_data), idx, data));
}
void *
BIO_get_ex_data(BIO *bio, int idx)
{
return (CRYPTO_get_ex_data(&(bio->ex_data), idx));
}
unsigned long
BIO_number_read(BIO *bio)
{
if (bio)
return bio->num_read;
return 0;
}
unsigned long
BIO_number_written(BIO *bio)
{
if (bio)
return bio->num_write;
return 0;
}

147
externals/libressl/crypto/bio/bio_meth.c vendored Executable file
View File

@@ -0,0 +1,147 @@
/* $OpenBSD: bio_meth.c,v 1.6 2018/06/02 04:41:12 tb Exp $ */
/*
* Copyright (c) 2018 Theo Buehler <tb@openbsd.org>
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#include <stdlib.h>
#include <openssl/bio.h>
BIO_METHOD *
BIO_meth_new(int type, const char *name)
{
BIO_METHOD *biom;
if ((biom = calloc(1, sizeof(*biom))) == NULL)
return NULL;
biom->type = type;
biom->name = name;
return biom;
}
void
BIO_meth_free(BIO_METHOD *biom)
{
free(biom);
}
int
(*BIO_meth_get_write(const BIO_METHOD *biom))(BIO *, const char *, int)
{
return biom->bwrite;
}
int
BIO_meth_set_write(BIO_METHOD *biom, int (*write)(BIO *, const char *, int))
{
biom->bwrite = write;
return 1;
}
int
(*BIO_meth_get_read(const BIO_METHOD *biom))(BIO *, char *, int)
{
return biom->bread;
}
int
BIO_meth_set_read(BIO_METHOD *biom, int (*read)(BIO *, char *, int))
{
biom->bread = read;
return 1;
}
int
(*BIO_meth_get_puts(const BIO_METHOD *biom))(BIO *, const char *)
{
return biom->bputs;
}
int
BIO_meth_set_puts(BIO_METHOD *biom, int (*puts)(BIO *, const char *))
{
biom->bputs = puts;
return 1;
}
int
(*BIO_meth_get_gets(const BIO_METHOD *biom))(BIO *, char *, int)
{
return biom->bgets;
}
int
BIO_meth_set_gets(BIO_METHOD *biom, int (*gets)(BIO *, char *, int))
{
biom->bgets = gets;
return 1;
}
long
(*BIO_meth_get_ctrl(const BIO_METHOD *biom))(BIO *, int, long, void *)
{
return biom->ctrl;
}
int
BIO_meth_set_ctrl(BIO_METHOD *biom, long (*ctrl)(BIO *, int, long, void *))
{
biom->ctrl = ctrl;
return 1;
}
int
(*BIO_meth_get_create(const BIO_METHOD *biom))(BIO *)
{
return biom->create;
}
int
BIO_meth_set_create(BIO_METHOD *biom, int (*create)(BIO *))
{
biom->create = create;
return 1;
}
int
(*BIO_meth_get_destroy(const BIO_METHOD *biom))(BIO *)
{
return biom->destroy;
}
int
BIO_meth_set_destroy(BIO_METHOD *biom, int (*destroy)(BIO *))
{
biom->destroy = destroy;
return 1;
}
long
(*BIO_meth_get_callback_ctrl(const BIO_METHOD *biom))(BIO *, int, BIO_info_cb *)
{
return
(long (*)(BIO *, int, BIO_info_cb *))biom->callback_ctrl; /* XXX */
}
int
BIO_meth_set_callback_ctrl(BIO_METHOD *biom,
long (*callback_ctrl)(BIO *, int, BIO_info_cb *))
{
biom->callback_ctrl =
(long (*)(BIO *, int, bio_info_cb *))callback_ctrl; /* XXX */
return 1;
}

453
externals/libressl/crypto/bio/bss_acpt.c vendored Executable file
View File

@@ -0,0 +1,453 @@
/* $OpenBSD: bss_acpt.c,v 1.29 2018/05/12 18:51:59 tb Exp $ */
/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
* All rights reserved.
*
* This package is an SSL implementation written
* by Eric Young (eay@cryptsoft.com).
* The implementation was written so as to conform with Netscapes SSL.
*
* This library is free for commercial and non-commercial use as long as
* the following conditions are aheared to. The following conditions
* apply to all code found in this distribution, be it the RC4, RSA,
* lhash, DES, etc., code; not just the SSL code. The SSL documentation
* included with this distribution is covered by the same copyright terms
* except that the holder is Tim Hudson (tjh@cryptsoft.com).
*
* Copyright remains Eric Young's, and as such any Copyright notices in
* the code are not to be removed.
* If this package is used in a product, Eric Young should be given attribution
* as the author of the parts of the library used.
* This can be in the form of a textual message at program startup or
* in documentation (online or textual) provided with the package.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* "This product includes cryptographic software written by
* Eric Young (eay@cryptsoft.com)"
* The word 'cryptographic' can be left out if the rouines from the library
* being used are not cryptographic related :-).
* 4. If you include any Windows specific code (or a derivative thereof) from
* the apps directory (application code) you must include an acknowledgement:
* "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
*
* THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* The licence and distribution terms for any publically available version or
* derivative of this code cannot be changed. i.e. this code cannot simply be
* copied and put under another distribution licence
* [including the GNU Public Licence.]
*/
#include <sys/socket.h>
#include <errno.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <openssl/bio.h>
#include <openssl/buffer.h>
#include <openssl/err.h>
#define SOCKET_PROTOCOL IPPROTO_TCP
typedef struct bio_accept_st {
int state;
char *param_addr;
int accept_sock;
int accept_nbio;
char *addr;
int nbio;
/* If 0, it means normal, if 1, do a connect on bind failure,
* and if there is no-one listening, bind with SO_REUSEADDR.
* If 2, always use SO_REUSEADDR. */
int bind_mode;
BIO *bio_chain;
} BIO_ACCEPT;
static int acpt_write(BIO *h, const char *buf, int num);
static int acpt_read(BIO *h, char *buf, int size);
static int acpt_puts(BIO *h, const char *str);
static long acpt_ctrl(BIO *h, int cmd, long arg1, void *arg2);
static int acpt_new(BIO *h);
static int acpt_free(BIO *data);
static int acpt_state(BIO *b, BIO_ACCEPT *c);
static void acpt_close_socket(BIO *data);
static BIO_ACCEPT *BIO_ACCEPT_new(void );
static void BIO_ACCEPT_free(BIO_ACCEPT *a);
#define ACPT_S_BEFORE 1
#define ACPT_S_GET_ACCEPT_SOCKET 2
#define ACPT_S_OK 3
static const BIO_METHOD methods_acceptp = {
.type = BIO_TYPE_ACCEPT,
.name = "socket accept",
.bwrite = acpt_write,
.bread = acpt_read,
.bputs = acpt_puts,
.ctrl = acpt_ctrl,
.create = acpt_new,
.destroy = acpt_free
};
const BIO_METHOD *
BIO_s_accept(void)
{
return (&methods_acceptp);
}
static int
acpt_new(BIO *bi)
{
BIO_ACCEPT *ba;
bi->init = 0;
bi->num = -1;
bi->flags = 0;
if ((ba = BIO_ACCEPT_new()) == NULL)
return (0);
bi->ptr = (char *)ba;
ba->state = ACPT_S_BEFORE;
bi->shutdown = 1;
return (1);
}
static BIO_ACCEPT *
BIO_ACCEPT_new(void)
{
BIO_ACCEPT *ret;
if ((ret = calloc(1, sizeof(BIO_ACCEPT))) == NULL)
return (NULL);
ret->accept_sock = -1;
ret->bind_mode = BIO_BIND_NORMAL;
return (ret);
}
static void
BIO_ACCEPT_free(BIO_ACCEPT *a)
{
if (a == NULL)
return;
free(a->param_addr);
free(a->addr);
BIO_free(a->bio_chain);
free(a);
}
static void
acpt_close_socket(BIO *bio)
{
BIO_ACCEPT *c;
c = (BIO_ACCEPT *)bio->ptr;
if (c->accept_sock != -1) {
shutdown(c->accept_sock, SHUT_RDWR);
close(c->accept_sock);
c->accept_sock = -1;
bio->num = -1;
}
}
static int
acpt_free(BIO *a)
{
BIO_ACCEPT *data;
if (a == NULL)
return (0);
data = (BIO_ACCEPT *)a->ptr;
if (a->shutdown) {
acpt_close_socket(a);
BIO_ACCEPT_free(data);
a->ptr = NULL;
a->flags = 0;
a->init = 0;
}
return (1);
}
static int
acpt_state(BIO *b, BIO_ACCEPT *c)
{
BIO *bio = NULL, *dbio;
int s = -1;
int i;
again:
switch (c->state) {
case ACPT_S_BEFORE:
if (c->param_addr == NULL) {
BIOerror(BIO_R_NO_ACCEPT_PORT_SPECIFIED);
return (-1);
}
s = BIO_get_accept_socket(c->param_addr, c->bind_mode);
if (s == -1)
return (-1);
if (c->accept_nbio) {
if (!BIO_socket_nbio(s, 1)) {
close(s);
BIOerror(BIO_R_ERROR_SETTING_NBIO_ON_ACCEPT_SOCKET);
return (-1);
}
}
c->accept_sock = s;
b->num = s;
c->state = ACPT_S_GET_ACCEPT_SOCKET;
return (1);
/* break; */
case ACPT_S_GET_ACCEPT_SOCKET:
if (b->next_bio != NULL) {
c->state = ACPT_S_OK;
goto again;
}
BIO_clear_retry_flags(b);
b->retry_reason = 0;
i = BIO_accept(c->accept_sock, &(c->addr));
/* -2 return means we should retry */
if (i == -2) {
BIO_set_retry_special(b);
b->retry_reason = BIO_RR_ACCEPT;
return -1;
}
if (i < 0)
return (i);
bio = BIO_new_socket(i, BIO_CLOSE);
if (bio == NULL)
goto err;
BIO_set_callback(bio, BIO_get_callback(b));
BIO_set_callback_arg(bio, BIO_get_callback_arg(b));
if (c->nbio) {
if (!BIO_socket_nbio(i, 1)) {
BIOerror(BIO_R_ERROR_SETTING_NBIO_ON_ACCEPTED_SOCKET);
goto err;
}
}
/* If the accept BIO has an bio_chain, we dup it and
* put the new socket at the end. */
if (c->bio_chain != NULL) {
if ((dbio = BIO_dup_chain(c->bio_chain)) == NULL)
goto err;
if (!BIO_push(dbio, bio)) goto err;
bio = dbio;
}
if (BIO_push(b, bio)
== NULL) goto err;
c->state = ACPT_S_OK;
return (1);
err:
if (bio != NULL)
BIO_free(bio);
return (0);
/* break; */
case ACPT_S_OK:
if (b->next_bio == NULL) {
c->state = ACPT_S_GET_ACCEPT_SOCKET;
goto again;
}
return (1);
/* break; */
default:
return (0);
/* break; */
}
}
static int
acpt_read(BIO *b, char *out, int outl)
{
int ret = 0;
BIO_ACCEPT *data;
BIO_clear_retry_flags(b);
data = (BIO_ACCEPT *)b->ptr;
while (b->next_bio == NULL) {
ret = acpt_state(b, data);
if (ret <= 0)
return (ret);
}
ret = BIO_read(b->next_bio, out, outl);
BIO_copy_next_retry(b);
return (ret);
}
static int
acpt_write(BIO *b, const char *in, int inl)
{
int ret;
BIO_ACCEPT *data;
BIO_clear_retry_flags(b);
data = (BIO_ACCEPT *)b->ptr;
while (b->next_bio == NULL) {
ret = acpt_state(b, data);
if (ret <= 0)
return (ret);
}
ret = BIO_write(b->next_bio, in, inl);
BIO_copy_next_retry(b);
return (ret);
}
static long
acpt_ctrl(BIO *b, int cmd, long num, void *ptr)
{
int *ip;
long ret = 1;
BIO_ACCEPT *data;
char **pp;
data = (BIO_ACCEPT *)b->ptr;
switch (cmd) {
case BIO_CTRL_RESET:
ret = 0;
data->state = ACPT_S_BEFORE;
acpt_close_socket(b);
b->flags = 0;
break;
case BIO_C_DO_STATE_MACHINE:
/* use this one to start the connection */
ret = (long)acpt_state(b, data);
break;
case BIO_C_SET_ACCEPT:
if (ptr != NULL) {
if (num == 0) {
b->init = 1;
free(data->param_addr);
data->param_addr = strdup(ptr);
} else if (num == 1) {
data->accept_nbio = (ptr != NULL);
} else if (num == 2) {
BIO_free(data->bio_chain);
data->bio_chain = (BIO *)ptr;
}
}
break;
case BIO_C_SET_NBIO:
data->nbio = (int)num;
break;
case BIO_C_SET_FD:
b->init = 1;
b->num= *((int *)ptr);
data->accept_sock = b->num;
data->state = ACPT_S_GET_ACCEPT_SOCKET;
b->shutdown = (int)num;
b->init = 1;
break;
case BIO_C_GET_FD:
if (b->init) {
ip = (int *)ptr;
if (ip != NULL)
*ip = data->accept_sock;
ret = data->accept_sock;
} else
ret = -1;
break;
case BIO_C_GET_ACCEPT:
if (b->init) {
if (ptr != NULL) {
pp = (char **)ptr;
*pp = data->param_addr;
} else
ret = -1;
} else
ret = -1;
break;
case BIO_CTRL_GET_CLOSE:
ret = b->shutdown;
break;
case BIO_CTRL_SET_CLOSE:
b->shutdown = (int)num;
break;
case BIO_CTRL_PENDING:
case BIO_CTRL_WPENDING:
ret = 0;
break;
case BIO_CTRL_FLUSH:
break;
case BIO_C_SET_BIND_MODE:
data->bind_mode = (int)num;
break;
case BIO_C_GET_BIND_MODE:
ret = (long)data->bind_mode;
break;
case BIO_CTRL_DUP:
/* dbio=(BIO *)ptr;
if (data->param_port) EAY EAY
BIO_set_port(dbio,data->param_port);
if (data->param_hostname)
BIO_set_hostname(dbio,data->param_hostname);
BIO_set_nbio(dbio,data->nbio);
*/
break;
default:
ret = 0;
break;
}
return (ret);
}
static int
acpt_puts(BIO *bp, const char *str)
{
int n, ret;
n = strlen(str);
ret = acpt_write(bp, str, n);
return (ret);
}
BIO *
BIO_new_accept(const char *str)
{
BIO *ret;
ret = BIO_new(BIO_s_accept());
if (ret == NULL)
return (NULL);
if (BIO_set_accept_port(ret, str))
return (ret);
else {
BIO_free(ret);
return (NULL);
}
}

883
externals/libressl/crypto/bio/bss_bio.c vendored Executable file
View File

@@ -0,0 +1,883 @@
/* $OpenBSD: bss_bio.c,v 1.24 2018/05/01 13:29:09 tb Exp $ */
/* ====================================================================
* Copyright (c) 1998-2003 The OpenSSL Project. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. All advertising materials mentioning features or use of this
* software must display the following acknowledgment:
* "This product includes software developed by the OpenSSL Project
* for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
*
* 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
* endorse or promote products derived from this software without
* prior written permission. For written permission, please contact
* openssl-core@openssl.org.
*
* 5. Products derived from this software may not be called "OpenSSL"
* nor may "OpenSSL" appear in their names without prior written
* permission of the OpenSSL Project.
*
* 6. Redistributions of any form whatsoever must retain the following
* acknowledgment:
* "This product includes software developed by the OpenSSL Project
* for use in the OpenSSL Toolkit (http://www.openssl.org/)"
*
* THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
* EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
* OF THE POSSIBILITY OF SUCH DAMAGE.
* ====================================================================
*
* This product includes cryptographic software written by Eric Young
* (eay@cryptsoft.com). This product includes software written by Tim
* Hudson (tjh@cryptsoft.com).
*
*/
/* Special method for a BIO where the other endpoint is also a BIO
* of this kind, handled by the same thread (i.e. the "peer" is actually
* ourselves, wearing a different hat).
* Such "BIO pairs" are mainly for using the SSL library with I/O interfaces
* for which no specific BIO method is available.
* See ssl/ssltest.c for some hints on how this can be used. */
/* BIO_DEBUG implies BIO_PAIR_DEBUG */
#ifdef BIO_DEBUG
# ifndef BIO_PAIR_DEBUG
# define BIO_PAIR_DEBUG
# endif
#endif
/* disable assert() unless BIO_PAIR_DEBUG has been defined */
#ifndef BIO_PAIR_DEBUG
# ifndef NDEBUG
# define NDEBUG
# endif
#endif
#include <assert.h>
#include <limits.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <openssl/bio.h>
#include <openssl/err.h>
#include <openssl/crypto.h>
static int bio_new(BIO *bio);
static int bio_free(BIO *bio);
static int bio_read(BIO *bio, char *buf, int size);
static int bio_write(BIO *bio, const char *buf, int num);
static long bio_ctrl(BIO *bio, int cmd, long num, void *ptr);
static int bio_puts(BIO *bio, const char *str);
static int bio_make_pair(BIO *bio1, BIO *bio2);
static void bio_destroy_pair(BIO *bio);
static const BIO_METHOD methods_biop = {
.type = BIO_TYPE_BIO,
.name = "BIO pair",
.bwrite = bio_write,
.bread = bio_read,
.bputs = bio_puts,
.ctrl = bio_ctrl,
.create = bio_new,
.destroy = bio_free
};
const BIO_METHOD *
BIO_s_bio(void)
{
return &methods_biop;
}
struct bio_bio_st {
BIO *peer; /* NULL if buf == NULL.
* If peer != NULL, then peer->ptr is also a bio_bio_st,
* and its "peer" member points back to us.
* peer != NULL iff init != 0 in the BIO. */
/* This is for what we write (i.e. reading uses peer's struct): */
int closed; /* valid iff peer != NULL */
size_t len; /* valid iff buf != NULL; 0 if peer == NULL */
size_t offset; /* valid iff buf != NULL; 0 if len == 0 */
size_t size;
char *buf; /* "size" elements (if != NULL) */
size_t request; /* valid iff peer != NULL; 0 if len != 0,
* otherwise set by peer to number of bytes
* it (unsuccessfully) tried to read,
* never more than buffer space (size-len) warrants. */
};
static int
bio_new(BIO *bio)
{
struct bio_bio_st *b;
b = malloc(sizeof *b);
if (b == NULL)
return 0;
b->peer = NULL;
b->size = 17 * 1024; /* enough for one TLS record (just a default) */
b->buf = NULL;
bio->ptr = b;
return 1;
}
static int
bio_free(BIO *bio)
{
struct bio_bio_st *b;
if (bio == NULL)
return 0;
b = bio->ptr;
assert(b != NULL);
if (b->peer)
bio_destroy_pair(bio);
free(b->buf);
free(b);
return 1;
}
static int
bio_read(BIO *bio, char *buf, int size_)
{
size_t size = size_;
size_t rest;
struct bio_bio_st *b, *peer_b;
BIO_clear_retry_flags(bio);
if (!bio->init)
return 0;
b = bio->ptr;
assert(b != NULL);
assert(b->peer != NULL);
peer_b = b->peer->ptr;
assert(peer_b != NULL);
assert(peer_b->buf != NULL);
peer_b->request = 0; /* will be set in "retry_read" situation */
if (buf == NULL || size == 0)
return 0;
if (peer_b->len == 0) {
if (peer_b->closed)
return 0; /* writer has closed, and no data is left */
else {
BIO_set_retry_read(bio); /* buffer is empty */
if (size <= peer_b->size)
peer_b->request = size;
else
/* don't ask for more than the peer can
* deliver in one write */
peer_b->request = peer_b->size;
return -1;
}
}
/* we can read */
if (peer_b->len < size)
size = peer_b->len;
/* now read "size" bytes */
rest = size;
assert(rest > 0);
do /* one or two iterations */
{
size_t chunk;
assert(rest <= peer_b->len);
if (peer_b->offset + rest <= peer_b->size)
chunk = rest;
else
/* wrap around ring buffer */
chunk = peer_b->size - peer_b->offset;
assert(peer_b->offset + chunk <= peer_b->size);
memcpy(buf, peer_b->buf + peer_b->offset, chunk);
peer_b->len -= chunk;
if (peer_b->len) {
peer_b->offset += chunk;
assert(peer_b->offset <= peer_b->size);
if (peer_b->offset == peer_b->size)
peer_b->offset = 0;
buf += chunk;
} else {
/* buffer now empty, no need to advance "buf" */
assert(chunk == rest);
peer_b->offset = 0;
}
rest -= chunk;
} while (rest);
return size;
}
/* non-copying interface: provide pointer to available data in buffer
* bio_nread0: return number of available bytes
* bio_nread: also advance index
* (example usage: bio_nread0(), read from buffer, bio_nread()
* or just bio_nread(), read from buffer)
*/
/* WARNING: The non-copying interface is largely untested as of yet
* and may contain bugs. */
static ssize_t
bio_nread0(BIO *bio, char **buf)
{
struct bio_bio_st *b, *peer_b;
ssize_t num;
BIO_clear_retry_flags(bio);
if (!bio->init)
return 0;
b = bio->ptr;
assert(b != NULL);
assert(b->peer != NULL);
peer_b = b->peer->ptr;
assert(peer_b != NULL);
assert(peer_b->buf != NULL);
peer_b->request = 0;
if (peer_b->len == 0) {
char dummy;
/* avoid code duplication -- nothing available for reading */
return bio_read(bio, &dummy, 1); /* returns 0 or -1 */
}
num = peer_b->len;
if (peer_b->size < peer_b->offset + num)
/* no ring buffer wrap-around for non-copying interface */
num = peer_b->size - peer_b->offset;
assert(num > 0);
if (buf != NULL)
*buf = peer_b->buf + peer_b->offset;
return num;
}
static ssize_t
bio_nread(BIO *bio, char **buf, size_t num_)
{
struct bio_bio_st *b, *peer_b;
ssize_t num, available;
if (num_ > SSIZE_MAX)
num = SSIZE_MAX;
else
num = (ssize_t)num_;
available = bio_nread0(bio, buf);
if (num > available)
num = available;
if (num <= 0)
return num;
b = bio->ptr;
peer_b = b->peer->ptr;
peer_b->len -= num;
if (peer_b->len) {
peer_b->offset += num;
assert(peer_b->offset <= peer_b->size);
if (peer_b->offset == peer_b->size)
peer_b->offset = 0;
} else
peer_b->offset = 0;
return num;
}
static int
bio_write(BIO *bio, const char *buf, int num_)
{
size_t num = num_;
size_t rest;
struct bio_bio_st *b;
BIO_clear_retry_flags(bio);
if (!bio->init || buf == NULL || num == 0)
return 0;
b = bio->ptr;
assert(b != NULL);
assert(b->peer != NULL);
assert(b->buf != NULL);
b->request = 0;
if (b->closed) {
/* we already closed */
BIOerror(BIO_R_BROKEN_PIPE);
return -1;
}
assert(b->len <= b->size);
if (b->len == b->size) {
BIO_set_retry_write(bio); /* buffer is full */
return -1;
}
/* we can write */
if (num > b->size - b->len)
num = b->size - b->len;
/* now write "num" bytes */
rest = num;
assert(rest > 0);
do /* one or two iterations */
{
size_t write_offset;
size_t chunk;
assert(b->len + rest <= b->size);
write_offset = b->offset + b->len;
if (write_offset >= b->size)
write_offset -= b->size;
/* b->buf[write_offset] is the first byte we can write to. */
if (write_offset + rest <= b->size)
chunk = rest;
else
/* wrap around ring buffer */
chunk = b->size - write_offset;
memcpy(b->buf + write_offset, buf, chunk);
b->len += chunk;
assert(b->len <= b->size);
rest -= chunk;
buf += chunk;
} while (rest);
return num;
}
/* non-copying interface: provide pointer to region to write to
* bio_nwrite0: check how much space is available
* bio_nwrite: also increase length
* (example usage: bio_nwrite0(), write to buffer, bio_nwrite()
* or just bio_nwrite(), write to buffer)
*/
static ssize_t
bio_nwrite0(BIO *bio, char **buf)
{
struct bio_bio_st *b;
size_t num;
size_t write_offset;
BIO_clear_retry_flags(bio);
if (!bio->init)
return 0;
b = bio->ptr;
assert(b != NULL);
assert(b->peer != NULL);
assert(b->buf != NULL);
b->request = 0;
if (b->closed) {
BIOerror(BIO_R_BROKEN_PIPE);
return -1;
}
assert(b->len <= b->size);
if (b->len == b->size) {
BIO_set_retry_write(bio);
return -1;
}
num = b->size - b->len;
write_offset = b->offset + b->len;
if (write_offset >= b->size)
write_offset -= b->size;
if (write_offset + num > b->size)
/* no ring buffer wrap-around for non-copying interface
* (to fulfil the promise by BIO_ctrl_get_write_guarantee,
* BIO_nwrite may have to be called twice) */
num = b->size - write_offset;
if (buf != NULL)
*buf = b->buf + write_offset;
assert(write_offset + num <= b->size);
return num;
}
static ssize_t
bio_nwrite(BIO *bio, char **buf, size_t num_)
{
struct bio_bio_st *b;
ssize_t num, space;
if (num_ > SSIZE_MAX)
num = SSIZE_MAX;
else
num = (ssize_t)num_;
space = bio_nwrite0(bio, buf);
if (num > space)
num = space;
if (num <= 0)
return num;
b = bio->ptr;
assert(b != NULL);
b->len += num;
assert(b->len <= b->size);
return num;
}
static long
bio_ctrl(BIO *bio, int cmd, long num, void *ptr)
{
long ret;
struct bio_bio_st *b = bio->ptr;
assert(b != NULL);
switch (cmd) {
/* specific CTRL codes */
case BIO_C_SET_WRITE_BUF_SIZE:
if (b->peer) {
BIOerror(BIO_R_IN_USE);
ret = 0;
} else if (num == 0) {
BIOerror(BIO_R_INVALID_ARGUMENT);
ret = 0;
} else {
size_t new_size = num;
if (b->size != new_size) {
free(b->buf);
b->buf = NULL;
b->size = new_size;
}
ret = 1;
}
break;
case BIO_C_GET_WRITE_BUF_SIZE:
ret = (long) b->size;
break;
case BIO_C_MAKE_BIO_PAIR:
{
BIO *other_bio = ptr;
if (bio_make_pair(bio, other_bio))
ret = 1;
else
ret = 0;
}
break;
case BIO_C_DESTROY_BIO_PAIR:
/* Affects both BIOs in the pair -- call just once!
* Or let BIO_free(bio1); BIO_free(bio2); do the job. */
bio_destroy_pair(bio);
ret = 1;
break;
case BIO_C_GET_WRITE_GUARANTEE:
/* How many bytes can the caller feed to the next write
* without having to keep any? */
if (b->peer == NULL || b->closed)
ret = 0;
else
ret = (long) b->size - b->len;
break;
case BIO_C_GET_READ_REQUEST:
/* If the peer unsuccessfully tried to read, how many bytes
* were requested? (As with BIO_CTRL_PENDING, that number
* can usually be treated as boolean.) */
ret = (long) b->request;
break;
case BIO_C_RESET_READ_REQUEST:
/* Reset request. (Can be useful after read attempts
* at the other side that are meant to be non-blocking,
* e.g. when probing SSL_read to see if any data is
* available.) */
b->request = 0;
ret = 1;
break;
case BIO_C_SHUTDOWN_WR:
/* similar to shutdown(..., SHUT_WR) */
b->closed = 1;
ret = 1;
break;
case BIO_C_NREAD0:
/* prepare for non-copying read */
ret = (long) bio_nread0(bio, ptr);
break;
case BIO_C_NREAD:
/* non-copying read */
ret = (long) bio_nread(bio, ptr, (size_t) num);
break;
case BIO_C_NWRITE0:
/* prepare for non-copying write */
ret = (long) bio_nwrite0(bio, ptr);
break;
case BIO_C_NWRITE:
/* non-copying write */
ret = (long) bio_nwrite(bio, ptr, (size_t) num);
break;
/* standard CTRL codes follow */
case BIO_CTRL_RESET:
if (b->buf != NULL) {
b->len = 0;
b->offset = 0;
}
ret = 0;
break;
case BIO_CTRL_GET_CLOSE:
ret = bio->shutdown;
break;
case BIO_CTRL_SET_CLOSE:
bio->shutdown = (int) num;
ret = 1;
break;
case BIO_CTRL_PENDING:
if (b->peer != NULL) {
struct bio_bio_st *peer_b = b->peer->ptr;
ret = (long) peer_b->len;
} else
ret = 0;
break;
case BIO_CTRL_WPENDING:
if (b->buf != NULL)
ret = (long) b->len;
else
ret = 0;
break;
case BIO_CTRL_DUP:
/* See BIO_dup_chain for circumstances we have to expect. */
{
BIO *other_bio = ptr;
struct bio_bio_st *other_b;
assert(other_bio != NULL);
other_b = other_bio->ptr;
assert(other_b != NULL);
assert(other_b->buf == NULL); /* other_bio is always fresh */
other_b->size = b->size;
}
ret = 1;
break;
case BIO_CTRL_FLUSH:
ret = 1;
break;
case BIO_CTRL_EOF:
{
BIO *other_bio = ptr;
if (other_bio) {
struct bio_bio_st *other_b = other_bio->ptr;
assert(other_b != NULL);
ret = other_b->len == 0 && other_b->closed;
} else
ret = 1;
}
break;
default:
ret = 0;
}
return ret;
}
static int
bio_puts(BIO *bio, const char *str)
{
return bio_write(bio, str, strlen(str));
}
static int
bio_make_pair(BIO *bio1, BIO *bio2)
{
struct bio_bio_st *b1, *b2;
assert(bio1 != NULL);
assert(bio2 != NULL);
b1 = bio1->ptr;
b2 = bio2->ptr;
if (b1->peer != NULL || b2->peer != NULL) {
BIOerror(BIO_R_IN_USE);
return 0;
}
if (b1->buf == NULL) {
b1->buf = malloc(b1->size);
if (b1->buf == NULL) {
BIOerror(ERR_R_MALLOC_FAILURE);
return 0;
}
b1->len = 0;
b1->offset = 0;
}
if (b2->buf == NULL) {
b2->buf = malloc(b2->size);
if (b2->buf == NULL) {
BIOerror(ERR_R_MALLOC_FAILURE);
return 0;
}
b2->len = 0;
b2->offset = 0;
}
b1->peer = bio2;
b1->closed = 0;
b1->request = 0;
b2->peer = bio1;
b2->closed = 0;
b2->request = 0;
bio1->init = 1;
bio2->init = 1;
return 1;
}
static void
bio_destroy_pair(BIO *bio)
{
struct bio_bio_st *b = bio->ptr;
if (b != NULL) {
BIO *peer_bio = b->peer;
if (peer_bio != NULL) {
struct bio_bio_st *peer_b = peer_bio->ptr;
assert(peer_b != NULL);
assert(peer_b->peer == bio);
peer_b->peer = NULL;
peer_bio->init = 0;
assert(peer_b->buf != NULL);
peer_b->len = 0;
peer_b->offset = 0;
b->peer = NULL;
bio->init = 0;
assert(b->buf != NULL);
b->len = 0;
b->offset = 0;
}
}
}
/* Exported convenience functions */
int
BIO_new_bio_pair(BIO **bio1_p, size_t writebuf1, BIO **bio2_p, size_t writebuf2)
{
BIO *bio1 = NULL, *bio2 = NULL;
long r;
int ret = 0;
bio1 = BIO_new(BIO_s_bio());
if (bio1 == NULL)
goto err;
bio2 = BIO_new(BIO_s_bio());
if (bio2 == NULL)
goto err;
if (writebuf1) {
r = BIO_set_write_buf_size(bio1, writebuf1);
if (!r)
goto err;
}
if (writebuf2) {
r = BIO_set_write_buf_size(bio2, writebuf2);
if (!r)
goto err;
}
r = BIO_make_bio_pair(bio1, bio2);
if (!r)
goto err;
ret = 1;
err:
if (ret == 0) {
if (bio1) {
BIO_free(bio1);
bio1 = NULL;
}
if (bio2) {
BIO_free(bio2);
bio2 = NULL;
}
}
*bio1_p = bio1;
*bio2_p = bio2;
return ret;
}
size_t
BIO_ctrl_get_write_guarantee(BIO *bio)
{
return BIO_ctrl(bio, BIO_C_GET_WRITE_GUARANTEE, 0, NULL);
}
size_t
BIO_ctrl_get_read_request(BIO *bio)
{
return BIO_ctrl(bio, BIO_C_GET_READ_REQUEST, 0, NULL);
}
int
BIO_ctrl_reset_read_request(BIO *bio)
{
return (BIO_ctrl(bio, BIO_C_RESET_READ_REQUEST, 0, NULL) != 0);
}
/* BIO_nread0/nread/nwrite0/nwrite are available only for BIO pairs for now
* (conceivably some other BIOs could allow non-copying reads and writes too.)
*/
int
BIO_nread0(BIO *bio, char **buf)
{
long ret;
if (!bio->init) {
BIOerror(BIO_R_UNINITIALIZED);
return -2;
}
ret = BIO_ctrl(bio, BIO_C_NREAD0, 0, buf);
if (ret > INT_MAX)
return INT_MAX;
else
return (int) ret;
}
int
BIO_nread(BIO *bio, char **buf, int num)
{
int ret;
if (!bio->init) {
BIOerror(BIO_R_UNINITIALIZED);
return -2;
}
ret = (int) BIO_ctrl(bio, BIO_C_NREAD, num, buf);
if (ret > 0)
bio->num_read += ret;
return ret;
}
int
BIO_nwrite0(BIO *bio, char **buf)
{
long ret;
if (!bio->init) {
BIOerror(BIO_R_UNINITIALIZED);
return -2;
}
ret = BIO_ctrl(bio, BIO_C_NWRITE0, 0, buf);
if (ret > INT_MAX)
return INT_MAX;
else
return (int) ret;
}
int
BIO_nwrite(BIO *bio, char **buf, int num)
{
int ret;
if (!bio->init) {
BIOerror(BIO_R_UNINITIALIZED);
return -2;
}
ret = BIO_ctrl(bio, BIO_C_NWRITE, num, buf);
if (ret > 0)
bio->num_write += ret;
return ret;
}

600
externals/libressl/crypto/bio/bss_conn.c vendored Executable file
View File

@@ -0,0 +1,600 @@
/* $OpenBSD: bss_conn.c,v 1.35 2018/05/12 18:51:59 tb Exp $ */
/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
* All rights reserved.
*
* This package is an SSL implementation written
* by Eric Young (eay@cryptsoft.com).
* The implementation was written so as to conform with Netscapes SSL.
*
* This library is free for commercial and non-commercial use as long as
* the following conditions are aheared to. The following conditions
* apply to all code found in this distribution, be it the RC4, RSA,
* lhash, DES, etc., code; not just the SSL code. The SSL documentation
* included with this distribution is covered by the same copyright terms
* except that the holder is Tim Hudson (tjh@cryptsoft.com).
*
* Copyright remains Eric Young's, and as such any Copyright notices in
* the code are not to be removed.
* If this package is used in a product, Eric Young should be given attribution
* as the author of the parts of the library used.
* This can be in the form of a textual message at program startup or
* in documentation (online or textual) provided with the package.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* "This product includes cryptographic software written by
* Eric Young (eay@cryptsoft.com)"
* The word 'cryptographic' can be left out if the rouines from the library
* being used are not cryptographic related :-).
* 4. If you include any Windows specific code (or a derivative thereof) from
* the apps directory (application code) you must include an acknowledgement:
* "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
*
* THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* The licence and distribution terms for any publically available version or
* derivative of this code cannot be changed. i.e. this code cannot simply be
* copied and put under another distribution licence
* [including the GNU Public Licence.]
*/
#include <sys/socket.h>
#include <netinet/in.h>
#include <errno.h>
#include <netdb.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <openssl/bio.h>
#include <openssl/buffer.h>
#include <openssl/err.h>
#define SOCKET_PROTOCOL IPPROTO_TCP
typedef struct bio_connect_st {
int state;
char *param_hostname;
char *param_port;
int nbio;
unsigned char ip[4];
unsigned short port;
struct sockaddr_in them;
/* int socket; this will be kept in bio->num so that it is
* compatible with the bss_sock bio */
/* called when the connection is initially made
* callback(BIO,state,ret); The callback should return
* 'ret'. state is for compatibility with the ssl info_callback */
int (*info_callback)(const BIO *bio, int state, int ret);
} BIO_CONNECT;
static int conn_write(BIO *h, const char *buf, int num);
static int conn_read(BIO *h, char *buf, int size);
static int conn_puts(BIO *h, const char *str);
static long conn_ctrl(BIO *h, int cmd, long arg1, void *arg2);
static int conn_new(BIO *h);
static int conn_free(BIO *data);
static long conn_callback_ctrl(BIO *h, int cmd, bio_info_cb *);
static int conn_state(BIO *b, BIO_CONNECT *c);
static void conn_close_socket(BIO *data);
BIO_CONNECT *BIO_CONNECT_new(void);
void BIO_CONNECT_free(BIO_CONNECT *a);
static const BIO_METHOD methods_connectp = {
.type = BIO_TYPE_CONNECT,
.name = "socket connect",
.bwrite = conn_write,
.bread = conn_read,
.bputs = conn_puts,
.ctrl = conn_ctrl,
.create = conn_new,
.destroy = conn_free,
.callback_ctrl = conn_callback_ctrl
};
static int
conn_state(BIO *b, BIO_CONNECT *c)
{
int ret = -1, i;
unsigned long l;
char *p, *q;
int (*cb)(const BIO *, int, int) = NULL;
if (c->info_callback != NULL)
cb = c->info_callback;
for (;;) {
switch (c->state) {
case BIO_CONN_S_BEFORE:
p = c->param_hostname;
if (p == NULL) {
BIOerror(BIO_R_NO_HOSTNAME_SPECIFIED);
goto exit_loop;
}
for (; *p != '\0'; p++) {
if ((*p == ':') || (*p == '/'))
break;
}
i= *p;
if ((i == ':') || (i == '/')) {
*(p++) = '\0';
if (i == ':') {
for (q = p; *q; q++)
if (*q == '/') {
*q = '\0';
break;
}
free(c->param_port);
c->param_port = strdup(p);
}
}
if (c->param_port == NULL) {
BIOerror(BIO_R_NO_PORT_SPECIFIED);
ERR_asprintf_error_data("host=%s",
c->param_hostname);
goto exit_loop;
}
c->state = BIO_CONN_S_GET_IP;
break;
case BIO_CONN_S_GET_IP:
if (BIO_get_host_ip(c->param_hostname, &(c->ip[0])) <= 0)
goto exit_loop;
c->state = BIO_CONN_S_GET_PORT;
break;
case BIO_CONN_S_GET_PORT:
if (c->param_port == NULL) {
/* abort(); */
goto exit_loop;
} else if (BIO_get_port(c->param_port, &c->port) <= 0)
goto exit_loop;
c->state = BIO_CONN_S_CREATE_SOCKET;
break;
case BIO_CONN_S_CREATE_SOCKET:
/* now setup address */
memset((char *)&c->them, 0, sizeof(c->them));
c->them.sin_family = AF_INET;
c->them.sin_port = htons((unsigned short)c->port);
l = (unsigned long)
((unsigned long)c->ip[0] << 24L)|
((unsigned long)c->ip[1] << 16L)|
((unsigned long)c->ip[2] << 8L)|
((unsigned long)c->ip[3]);
c->them.sin_addr.s_addr = htonl(l);
c->state = BIO_CONN_S_CREATE_SOCKET;
ret = socket(AF_INET, SOCK_STREAM, SOCKET_PROTOCOL);
if (ret == -1) {
SYSerror(errno);
ERR_asprintf_error_data("host=%s:%s",
c->param_hostname, c->param_port);
BIOerror(BIO_R_UNABLE_TO_CREATE_SOCKET);
goto exit_loop;
}
b->num = ret;
c->state = BIO_CONN_S_NBIO;
break;
case BIO_CONN_S_NBIO:
if (c->nbio) {
if (!BIO_socket_nbio(b->num, 1)) {
BIOerror(BIO_R_ERROR_SETTING_NBIO);
ERR_asprintf_error_data("host=%s:%s",
c->param_hostname, c->param_port);
goto exit_loop;
}
}
c->state = BIO_CONN_S_CONNECT;
#if defined(SO_KEEPALIVE)
i = 1;
i = setsockopt(b->num, SOL_SOCKET, SO_KEEPALIVE, &i, sizeof(i));
if (i < 0) {
SYSerror(errno);
ERR_asprintf_error_data("host=%s:%s",
c->param_hostname, c->param_port);
BIOerror(BIO_R_KEEPALIVE);
goto exit_loop;
}
#endif
break;
case BIO_CONN_S_CONNECT:
BIO_clear_retry_flags(b);
ret = connect(b->num,
(struct sockaddr *)&c->them,
sizeof(c->them));
b->retry_reason = 0;
if (ret < 0) {
if (BIO_sock_should_retry(ret)) {
BIO_set_retry_special(b);
c->state = BIO_CONN_S_BLOCKED_CONNECT;
b->retry_reason = BIO_RR_CONNECT;
} else {
SYSerror(errno);
ERR_asprintf_error_data("host=%s:%s",
c->param_hostname, c->param_port);
BIOerror(BIO_R_CONNECT_ERROR);
}
goto exit_loop;
} else
c->state = BIO_CONN_S_OK;
break;
case BIO_CONN_S_BLOCKED_CONNECT:
i = BIO_sock_error(b->num);
if (i) {
BIO_clear_retry_flags(b);
SYSerror(i);
ERR_asprintf_error_data("host=%s:%s",
c->param_hostname, c->param_port);
BIOerror(BIO_R_NBIO_CONNECT_ERROR);
ret = 0;
goto exit_loop;
} else
c->state = BIO_CONN_S_OK;
break;
case BIO_CONN_S_OK:
ret = 1;
goto exit_loop;
default:
/* abort(); */
goto exit_loop;
}
if (cb != NULL) {
if (!(ret = cb((BIO *)b, c->state, ret)))
goto end;
}
}
/* Loop does not exit */
exit_loop:
if (cb != NULL)
ret = cb((BIO *)b, c->state, ret);
end:
return (ret);
}
BIO_CONNECT *
BIO_CONNECT_new(void)
{
BIO_CONNECT *ret;
if ((ret = malloc(sizeof(BIO_CONNECT))) == NULL)
return (NULL);
ret->state = BIO_CONN_S_BEFORE;
ret->param_hostname = NULL;
ret->param_port = NULL;
ret->info_callback = NULL;
ret->nbio = 0;
ret->ip[0] = 0;
ret->ip[1] = 0;
ret->ip[2] = 0;
ret->ip[3] = 0;
ret->port = 0;
memset((char *)&ret->them, 0, sizeof(ret->them));
return (ret);
}
void
BIO_CONNECT_free(BIO_CONNECT *a)
{
if (a == NULL)
return;
free(a->param_hostname);
free(a->param_port);
free(a);
}
const BIO_METHOD *
BIO_s_connect(void)
{
return (&methods_connectp);
}
static int
conn_new(BIO *bi)
{
bi->init = 0;
bi->num = -1;
bi->flags = 0;
if ((bi->ptr = (char *)BIO_CONNECT_new()) == NULL)
return (0);
else
return (1);
}
static void
conn_close_socket(BIO *bio)
{
BIO_CONNECT *c;
c = (BIO_CONNECT *)bio->ptr;
if (bio->num != -1) {
/* Only do a shutdown if things were established */
if (c->state == BIO_CONN_S_OK)
shutdown(bio->num, SHUT_RDWR);
close(bio->num);
bio->num = -1;
}
}
static int
conn_free(BIO *a)
{
BIO_CONNECT *data;
if (a == NULL)
return (0);
data = (BIO_CONNECT *)a->ptr;
if (a->shutdown) {
conn_close_socket(a);
BIO_CONNECT_free(data);
a->ptr = NULL;
a->flags = 0;
a->init = 0;
}
return (1);
}
static int
conn_read(BIO *b, char *out, int outl)
{
int ret = 0;
BIO_CONNECT *data;
data = (BIO_CONNECT *)b->ptr;
if (data->state != BIO_CONN_S_OK) {
ret = conn_state(b, data);
if (ret <= 0)
return (ret);
}
if (out != NULL) {
errno = 0;
ret = read(b->num, out, outl);
BIO_clear_retry_flags(b);
if (ret <= 0) {
if (BIO_sock_should_retry(ret))
BIO_set_retry_read(b);
}
}
return (ret);
}
static int
conn_write(BIO *b, const char *in, int inl)
{
int ret;
BIO_CONNECT *data;
data = (BIO_CONNECT *)b->ptr;
if (data->state != BIO_CONN_S_OK) {
ret = conn_state(b, data);
if (ret <= 0)
return (ret);
}
errno = 0;
ret = write(b->num, in, inl);
BIO_clear_retry_flags(b);
if (ret <= 0) {
if (BIO_sock_should_retry(ret))
BIO_set_retry_write(b);
}
return (ret);
}
static long
conn_ctrl(BIO *b, int cmd, long num, void *ptr)
{
BIO *dbio;
int *ip;
const char **pptr;
long ret = 1;
BIO_CONNECT *data;
data = (BIO_CONNECT *)b->ptr;
switch (cmd) {
case BIO_CTRL_RESET:
ret = 0;
data->state = BIO_CONN_S_BEFORE;
conn_close_socket(b);
b->flags = 0;
break;
case BIO_C_DO_STATE_MACHINE:
/* use this one to start the connection */
if (data->state != BIO_CONN_S_OK)
ret = (long)conn_state(b, data);
else
ret = 1;
break;
case BIO_C_GET_CONNECT:
if (ptr != NULL) {
pptr = (const char **)ptr;
if (num == 0) {
*pptr = data->param_hostname;
} else if (num == 1) {
*pptr = data->param_port;
} else if (num == 2) {
*pptr = (char *)&(data->ip[0]);
} else if (num == 3) {
*((int *)ptr) = data->port;
}
if ((!b->init) || (ptr == NULL))
*pptr = "not initialized";
ret = 1;
}
break;
case BIO_C_SET_CONNECT:
if (ptr != NULL) {
b->init = 1;
if (num == 0) {
free(data->param_hostname);
data->param_hostname = strdup(ptr);
} else if (num == 1) {
free(data->param_port);
data->param_port = strdup(ptr);
} else if (num == 2) {
unsigned char *p = ptr;
free(data->param_hostname);
if (asprintf(&data->param_hostname,
"%u.%u.%u.%u", p[0], p[1],
p[2], p[3]) == -1)
data->param_hostname = NULL;
memcpy(&(data->ip[0]), ptr, 4);
} else if (num == 3) {
free(data->param_port);
data->port= *(int *)ptr;
if (asprintf(&data->param_port, "%d",
data->port) == -1)
data->param_port = NULL;
}
}
break;
case BIO_C_SET_NBIO:
data->nbio = (int)num;
break;
case BIO_C_GET_FD:
if (b->init) {
ip = (int *)ptr;
if (ip != NULL)
*ip = b->num;
ret = b->num;
} else
ret = -1;
break;
case BIO_CTRL_GET_CLOSE:
ret = b->shutdown;
break;
case BIO_CTRL_SET_CLOSE:
b->shutdown = (int)num;
break;
case BIO_CTRL_PENDING:
case BIO_CTRL_WPENDING:
ret = 0;
break;
case BIO_CTRL_FLUSH:
break;
case BIO_CTRL_DUP:
{
dbio = (BIO *)ptr;
if (data->param_port)
BIO_set_conn_port(dbio, data->param_port);
if (data->param_hostname)
BIO_set_conn_hostname(dbio,
data->param_hostname);
BIO_set_nbio(dbio, data->nbio);
/* FIXME: the cast of the function seems unlikely to be a good idea */
(void)BIO_set_info_callback(dbio,
(bio_info_cb *)data->info_callback);
}
break;
case BIO_CTRL_SET_CALLBACK:
{
#if 0 /* FIXME: Should this be used? -- Richard Levitte */
BIOerror(ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
ret = -1;
#else
ret = 0;
#endif
}
break;
case BIO_CTRL_GET_CALLBACK:
{
int (**fptr)(const BIO *bio, int state, int xret);
fptr = (int (**)(const BIO *bio, int state, int xret))ptr;
*fptr = data->info_callback;
}
break;
default:
ret = 0;
break;
}
return (ret);
}
static long
conn_callback_ctrl(BIO *b, int cmd, bio_info_cb *fp)
{
long ret = 1;
BIO_CONNECT *data;
data = (BIO_CONNECT *)b->ptr;
switch (cmd) {
case BIO_CTRL_SET_CALLBACK:
{
data->info_callback = (int (*)(const struct bio_st *, int, int))fp;
}
break;
default:
ret = 0;
break;
}
return (ret);
}
static int
conn_puts(BIO *bp, const char *str)
{
int n, ret;
n = strlen(str);
ret = conn_write(bp, str, n);
return (ret);
}
BIO *
BIO_new_connect(const char *str)
{
BIO *ret;
ret = BIO_new(BIO_s_connect());
if (ret == NULL)
return (NULL);
if (BIO_set_conn_hostname(ret, str))
return (ret);
else {
BIO_free(ret);
return (NULL);
}
}

658
externals/libressl/crypto/bio/bss_dgram.c vendored Executable file
View File

@@ -0,0 +1,658 @@
/* $OpenBSD: bss_dgram.c,v 1.42 2018/05/12 17:47:53 tb Exp $ */
/*
* DTLS implementation written by Nagendra Modadugu
* (nagendra@cs.stanford.edu) for the OpenSSL project 2005.
*/
/* ====================================================================
* Copyright (c) 1999-2005 The OpenSSL Project. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. All advertising materials mentioning features or use of this
* software must display the following acknowledgment:
* "This product includes software developed by the OpenSSL Project
* for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
*
* 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
* endorse or promote products derived from this software without
* prior written permission. For written permission, please contact
* openssl-core@OpenSSL.org.
*
* 5. Products derived from this software may not be called "OpenSSL"
* nor may "OpenSSL" appear in their names without prior written
* permission of the OpenSSL Project.
*
* 6. Redistributions of any form whatsoever must retain the following
* acknowledgment:
* "This product includes software developed by the OpenSSL Project
* for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
*
* THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
* EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
* OF THE POSSIBILITY OF SUCH DAMAGE.
* ====================================================================
*
* This product includes cryptographic software written by Eric Young
* (eay@cryptsoft.com). This product includes software written by Tim
* Hudson (tjh@cryptsoft.com).
*
*/
#include <sys/socket.h>
#include <sys/time.h>
#include <netinet/in.h>
#include <errno.h>
#include <netdb.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <openssl/opensslconf.h>
#include <openssl/bio.h>
#ifndef OPENSSL_NO_DGRAM
static int dgram_write(BIO *h, const char *buf, int num);
static int dgram_read(BIO *h, char *buf, int size);
static int dgram_puts(BIO *h, const char *str);
static long dgram_ctrl(BIO *h, int cmd, long arg1, void *arg2);
static int dgram_new(BIO *h);
static int dgram_free(BIO *data);
static int dgram_clear(BIO *bio);
static int BIO_dgram_should_retry(int s);
static const BIO_METHOD methods_dgramp = {
.type = BIO_TYPE_DGRAM,
.name = "datagram socket",
.bwrite = dgram_write,
.bread = dgram_read,
.bputs = dgram_puts,
.ctrl = dgram_ctrl,
.create = dgram_new,
.destroy = dgram_free
};
typedef struct bio_dgram_data_st {
union {
struct sockaddr sa;
struct sockaddr_in sa_in;
struct sockaddr_in6 sa_in6;
} peer;
unsigned int connected;
unsigned int _errno;
unsigned int mtu;
struct timeval next_timeout;
struct timeval socket_timeout;
} bio_dgram_data;
const BIO_METHOD *
BIO_s_datagram(void)
{
return (&methods_dgramp);
}
BIO *
BIO_new_dgram(int fd, int close_flag)
{
BIO *ret;
ret = BIO_new(BIO_s_datagram());
if (ret == NULL)
return (NULL);
BIO_set_fd(ret, fd, close_flag);
return (ret);
}
static int
dgram_new(BIO *bi)
{
bio_dgram_data *data = NULL;
bi->init = 0;
bi->num = 0;
data = calloc(1, sizeof(bio_dgram_data));
if (data == NULL)
return 0;
bi->ptr = data;
bi->flags = 0;
return (1);
}
static int
dgram_free(BIO *a)
{
bio_dgram_data *data;
if (a == NULL)
return (0);
if (!dgram_clear(a))
return 0;
data = (bio_dgram_data *)a->ptr;
free(data);
return (1);
}
static int
dgram_clear(BIO *a)
{
if (a == NULL)
return (0);
if (a->shutdown) {
if (a->init) {
shutdown(a->num, SHUT_RDWR);
close(a->num);
}
a->init = 0;
a->flags = 0;
}
return (1);
}
static void
dgram_adjust_rcv_timeout(BIO *b)
{
#if defined(SO_RCVTIMEO)
bio_dgram_data *data = (bio_dgram_data *)b->ptr;
/* Is a timer active? */
if (data->next_timeout.tv_sec > 0 || data->next_timeout.tv_usec > 0) {
struct timeval timenow, timeleft;
/* Read current socket timeout */
socklen_t sz = sizeof(data->socket_timeout);
if (getsockopt(b->num, SOL_SOCKET, SO_RCVTIMEO,
&(data->socket_timeout), &sz) < 0) {
perror("getsockopt");
}
/* Get current time */
gettimeofday(&timenow, NULL);
/* Calculate time left until timer expires */
memcpy(&timeleft, &(data->next_timeout), sizeof(struct timeval));
timeleft.tv_sec -= timenow.tv_sec;
timeleft.tv_usec -= timenow.tv_usec;
if (timeleft.tv_usec < 0) {
timeleft.tv_sec--;
timeleft.tv_usec += 1000000;
}
if (timeleft.tv_sec < 0) {
timeleft.tv_sec = 0;
timeleft.tv_usec = 1;
}
/* Adjust socket timeout if next handhake message timer
* will expire earlier.
*/
if ((data->socket_timeout.tv_sec == 0 &&
data->socket_timeout.tv_usec == 0) ||
(data->socket_timeout.tv_sec > timeleft.tv_sec) ||
(data->socket_timeout.tv_sec == timeleft.tv_sec &&
data->socket_timeout.tv_usec >= timeleft.tv_usec)) {
if (setsockopt(b->num, SOL_SOCKET, SO_RCVTIMEO,
&timeleft, sizeof(struct timeval)) < 0) {
perror("setsockopt");
}
}
}
#endif
}
static void
dgram_reset_rcv_timeout(BIO *b)
{
#if defined(SO_RCVTIMEO)
bio_dgram_data *data = (bio_dgram_data *)b->ptr;
/* Is a timer active? */
if (data->next_timeout.tv_sec > 0 || data->next_timeout.tv_usec > 0) {
if (setsockopt(b->num, SOL_SOCKET, SO_RCVTIMEO,
&(data->socket_timeout), sizeof(struct timeval)) < 0) {
perror("setsockopt");
}
}
#endif
}
static int
dgram_read(BIO *b, char *out, int outl)
{
int ret = 0;
bio_dgram_data *data = (bio_dgram_data *)b->ptr;
struct {
socklen_t len;
union {
struct sockaddr sa;
struct sockaddr_in sa_in;
struct sockaddr_in6 sa_in6;
} peer;
} sa;
sa.len = sizeof(sa.peer);
if (out != NULL) {
errno = 0;
memset(&sa.peer, 0, sizeof(sa.peer));
dgram_adjust_rcv_timeout(b);
ret = recvfrom(b->num, out, outl, 0, &sa.peer.sa, &sa.len);
if (! data->connected && ret >= 0)
BIO_ctrl(b, BIO_CTRL_DGRAM_SET_PEER, 0, &sa.peer);
BIO_clear_retry_flags(b);
if (ret < 0) {
if (BIO_dgram_should_retry(ret)) {
BIO_set_retry_read(b);
data->_errno = errno;
}
}
dgram_reset_rcv_timeout(b);
}
return (ret);
}
static int
dgram_write(BIO *b, const char *in, int inl)
{
int ret;
bio_dgram_data *data = (bio_dgram_data *)b->ptr;
errno = 0;
if (data->connected)
ret = write(b->num, in, inl);
else {
int peerlen = sizeof(data->peer);
if (data->peer.sa.sa_family == AF_INET)
peerlen = sizeof(data->peer.sa_in);
else if (data->peer.sa.sa_family == AF_INET6)
peerlen = sizeof(data->peer.sa_in6);
ret = sendto(b->num, in, inl, 0, &data->peer.sa, peerlen);
}
BIO_clear_retry_flags(b);
if (ret <= 0) {
if (BIO_dgram_should_retry(ret)) {
BIO_set_retry_write(b);
data->_errno = errno;
/*
* higher layers are responsible for querying MTU,
* if necessary
*/
}
}
return (ret);
}
static long
dgram_ctrl(BIO *b, int cmd, long num, void *ptr)
{
long ret = 1;
int *ip;
struct sockaddr *to = NULL;
bio_dgram_data *data = NULL;
#if (defined(IP_MTU_DISCOVER) || defined(IP_MTU))
int sockopt_val = 0;
socklen_t sockopt_len; /* assume that system supporting IP_MTU is
* modern enough to define socklen_t */
socklen_t addr_len;
union {
struct sockaddr sa;
struct sockaddr_in s4;
struct sockaddr_in6 s6;
} addr;
#endif
data = (bio_dgram_data *)b->ptr;
switch (cmd) {
case BIO_CTRL_RESET:
num = 0;
case BIO_C_FILE_SEEK:
ret = 0;
break;
case BIO_C_FILE_TELL:
case BIO_CTRL_INFO:
ret = 0;
break;
case BIO_C_SET_FD:
dgram_clear(b);
b->num= *((int *)ptr);
b->shutdown = (int)num;
b->init = 1;
break;
case BIO_C_GET_FD:
if (b->init) {
ip = (int *)ptr;
if (ip != NULL)
*ip = b->num;
ret = b->num;
} else
ret = -1;
break;
case BIO_CTRL_GET_CLOSE:
ret = b->shutdown;
break;
case BIO_CTRL_SET_CLOSE:
b->shutdown = (int)num;
break;
case BIO_CTRL_PENDING:
case BIO_CTRL_WPENDING:
ret = 0;
break;
case BIO_CTRL_DUP:
case BIO_CTRL_FLUSH:
ret = 1;
break;
case BIO_CTRL_DGRAM_CONNECT:
to = (struct sockaddr *)ptr;
switch (to->sa_family) {
case AF_INET:
memcpy(&data->peer, to, sizeof(data->peer.sa_in));
break;
case AF_INET6:
memcpy(&data->peer, to, sizeof(data->peer.sa_in6));
break;
default:
memcpy(&data->peer, to, sizeof(data->peer.sa));
break;
}
break;
/* (Linux)kernel sets DF bit on outgoing IP packets */
case BIO_CTRL_DGRAM_MTU_DISCOVER:
#if defined(IP_MTU_DISCOVER) && defined(IP_PMTUDISC_DO)
addr_len = (socklen_t)sizeof(addr);
memset((void *)&addr, 0, sizeof(addr));
if (getsockname(b->num, &addr.sa, &addr_len) < 0) {
ret = 0;
break;
}
switch (addr.sa.sa_family) {
case AF_INET:
sockopt_val = IP_PMTUDISC_DO;
ret = setsockopt(b->num, IPPROTO_IP, IP_MTU_DISCOVER,
&sockopt_val, sizeof(sockopt_val));
if (ret < 0)
perror("setsockopt");
break;
#if defined(IPV6_MTU_DISCOVER) && defined(IPV6_PMTUDISC_DO)
case AF_INET6:
sockopt_val = IPV6_PMTUDISC_DO;
ret = setsockopt(b->num, IPPROTO_IPV6,
IPV6_MTU_DISCOVER, &sockopt_val,
sizeof(sockopt_val));
if (ret < 0)
perror("setsockopt");
break;
#endif
default:
ret = -1;
break;
}
#else
ret = -1;
#endif
break;
case BIO_CTRL_DGRAM_QUERY_MTU:
#if defined(IP_MTU)
addr_len = (socklen_t)sizeof(addr);
memset((void *)&addr, 0, sizeof(addr));
if (getsockname(b->num, &addr.sa, &addr_len) < 0) {
ret = 0;
break;
}
sockopt_len = sizeof(sockopt_val);
switch (addr.sa.sa_family) {
case AF_INET:
ret = getsockopt(b->num, IPPROTO_IP, IP_MTU,
&sockopt_val, &sockopt_len);
if (ret < 0 || sockopt_val < 0) {
ret = 0;
} else {
/* we assume that the transport protocol is UDP and no
* IP options are used.
*/
data->mtu = sockopt_val - 8 - 20;
ret = data->mtu;
}
break;
#if defined(IPV6_MTU)
case AF_INET6:
ret = getsockopt(b->num, IPPROTO_IPV6, IPV6_MTU,
&sockopt_val, &sockopt_len);
if (ret < 0 || sockopt_val < 0) {
ret = 0;
} else {
/* we assume that the transport protocol is UDP and no
* IPV6 options are used.
*/
data->mtu = sockopt_val - 8 - 40;
ret = data->mtu;
}
break;
#endif
default:
ret = 0;
break;
}
#else
ret = 0;
#endif
break;
case BIO_CTRL_DGRAM_GET_FALLBACK_MTU:
switch (data->peer.sa.sa_family) {
case AF_INET:
ret = 576 - 20 - 8;
break;
case AF_INET6:
#ifdef IN6_IS_ADDR_V4MAPPED
if (IN6_IS_ADDR_V4MAPPED(&data->peer.sa_in6.sin6_addr))
ret = 576 - 20 - 8;
else
#endif
ret = 1280 - 40 - 8;
break;
default:
ret = 576 - 20 - 8;
break;
}
break;
case BIO_CTRL_DGRAM_GET_MTU:
return data->mtu;
break;
case BIO_CTRL_DGRAM_SET_MTU:
data->mtu = num;
ret = num;
break;
case BIO_CTRL_DGRAM_SET_CONNECTED:
to = (struct sockaddr *)ptr;
if (to != NULL) {
data->connected = 1;
switch (to->sa_family) {
case AF_INET:
memcpy(&data->peer, to, sizeof(data->peer.sa_in));
break;
case AF_INET6:
memcpy(&data->peer, to, sizeof(data->peer.sa_in6));
break;
default:
memcpy(&data->peer, to, sizeof(data->peer.sa));
break;
}
} else {
data->connected = 0;
memset(&(data->peer), 0, sizeof(data->peer));
}
break;
case BIO_CTRL_DGRAM_GET_PEER:
switch (data->peer.sa.sa_family) {
case AF_INET:
ret = sizeof(data->peer.sa_in);
break;
case AF_INET6:
ret = sizeof(data->peer.sa_in6);
break;
default:
ret = sizeof(data->peer.sa);
break;
}
if (num == 0 || num > ret)
num = ret;
memcpy(ptr, &data->peer, (ret = num));
break;
case BIO_CTRL_DGRAM_SET_PEER:
to = (struct sockaddr *) ptr;
switch (to->sa_family) {
case AF_INET:
memcpy(&data->peer, to, sizeof(data->peer.sa_in));
break;
case AF_INET6:
memcpy(&data->peer, to, sizeof(data->peer.sa_in6));
break;
default:
memcpy(&data->peer, to, sizeof(data->peer.sa));
break;
}
break;
case BIO_CTRL_DGRAM_SET_NEXT_TIMEOUT:
memcpy(&(data->next_timeout), ptr, sizeof(struct timeval));
break;
#if defined(SO_RCVTIMEO)
case BIO_CTRL_DGRAM_SET_RECV_TIMEOUT:
if (setsockopt(b->num, SOL_SOCKET, SO_RCVTIMEO, ptr,
sizeof(struct timeval)) < 0) {
perror("setsockopt");
ret = -1;
}
break;
case BIO_CTRL_DGRAM_GET_RECV_TIMEOUT:
{
socklen_t sz = sizeof(struct timeval);
if (getsockopt(b->num, SOL_SOCKET, SO_RCVTIMEO,
ptr, &sz) < 0) {
perror("getsockopt");
ret = -1;
} else
ret = sz;
}
break;
#endif
#if defined(SO_SNDTIMEO)
case BIO_CTRL_DGRAM_SET_SEND_TIMEOUT:
if (setsockopt(b->num, SOL_SOCKET, SO_SNDTIMEO, ptr,
sizeof(struct timeval)) < 0) {
perror("setsockopt");
ret = -1;
}
break;
case BIO_CTRL_DGRAM_GET_SEND_TIMEOUT:
{
socklen_t sz = sizeof(struct timeval);
if (getsockopt(b->num, SOL_SOCKET, SO_SNDTIMEO,
ptr, &sz) < 0) {
perror("getsockopt");
ret = -1;
} else
ret = sz;
}
break;
#endif
case BIO_CTRL_DGRAM_GET_SEND_TIMER_EXP:
/* fall-through */
case BIO_CTRL_DGRAM_GET_RECV_TIMER_EXP:
if (data->_errno == EAGAIN) {
ret = 1;
data->_errno = 0;
} else
ret = 0;
break;
#ifdef EMSGSIZE
case BIO_CTRL_DGRAM_MTU_EXCEEDED:
if (data->_errno == EMSGSIZE) {
ret = 1;
data->_errno = 0;
} else
ret = 0;
break;
#endif
default:
ret = 0;
break;
}
return (ret);
}
static int
dgram_puts(BIO *bp, const char *str)
{
int n, ret;
n = strlen(str);
ret = dgram_write(bp, str, n);
return (ret);
}
static int
BIO_dgram_should_retry(int i)
{
int err;
if ((i == 0) || (i == -1)) {
err = errno;
return (BIO_dgram_non_fatal_error(err));
}
return (0);
}
int
BIO_dgram_non_fatal_error(int err)
{
switch (err) {
case EINTR:
case EAGAIN:
case EINPROGRESS:
case EALREADY:
return (1);
default:
break;
}
return (0);
}
#endif

267
externals/libressl/crypto/bio/bss_fd.c vendored Executable file
View File

@@ -0,0 +1,267 @@
/* $OpenBSD: bss_fd.c,v 1.19 2018/05/01 13:29:09 tb Exp $ */
/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
* All rights reserved.
*
* This package is an SSL implementation written
* by Eric Young (eay@cryptsoft.com).
* The implementation was written so as to conform with Netscapes SSL.
*
* This library is free for commercial and non-commercial use as long as
* the following conditions are aheared to. The following conditions
* apply to all code found in this distribution, be it the RC4, RSA,
* lhash, DES, etc., code; not just the SSL code. The SSL documentation
* included with this distribution is covered by the same copyright terms
* except that the holder is Tim Hudson (tjh@cryptsoft.com).
*
* Copyright remains Eric Young's, and as such any Copyright notices in
* the code are not to be removed.
* If this package is used in a product, Eric Young should be given attribution
* as the author of the parts of the library used.
* This can be in the form of a textual message at program startup or
* in documentation (online or textual) provided with the package.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* "This product includes cryptographic software written by
* Eric Young (eay@cryptsoft.com)"
* The word 'cryptographic' can be left out if the rouines from the library
* being used are not cryptographic related :-).
* 4. If you include any Windows specific code (or a derivative thereof) from
* the apps directory (application code) you must include an acknowledgement:
* "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
*
* THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* The licence and distribution terms for any publically available version or
* derivative of this code cannot be changed. i.e. this code cannot simply be
* copied and put under another distribution licence
* [including the GNU Public Licence.]
*/
#include <errno.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <openssl/opensslconf.h>
#include <openssl/bio.h>
static int fd_write(BIO *h, const char *buf, int num);
static int fd_read(BIO *h, char *buf, int size);
static int fd_puts(BIO *h, const char *str);
static int fd_gets(BIO *h, char *buf, int size);
static long fd_ctrl(BIO *h, int cmd, long arg1, void *arg2);
static int fd_new(BIO *h);
static int fd_free(BIO *data);
int BIO_fd_should_retry(int s);
static const BIO_METHOD methods_fdp = {
.type = BIO_TYPE_FD,
.name = "file descriptor",
.bwrite = fd_write,
.bread = fd_read,
.bputs = fd_puts,
.bgets = fd_gets,
.ctrl = fd_ctrl,
.create = fd_new,
.destroy = fd_free
};
const BIO_METHOD *
BIO_s_fd(void)
{
return (&methods_fdp);
}
BIO *
BIO_new_fd(int fd, int close_flag)
{
BIO *ret;
ret = BIO_new(BIO_s_fd());
if (ret == NULL)
return (NULL);
BIO_set_fd(ret, fd, close_flag);
return (ret);
}
static int
fd_new(BIO *bi)
{
bi->init = 0;
bi->num = -1;
bi->ptr = NULL;
bi->flags=0;
return (1);
}
static int
fd_free(BIO *a)
{
if (a == NULL)
return (0);
if (a->shutdown) {
if (a->init) {
close(a->num);
}
a->init = 0;
a->flags = 0;
}
return (1);
}
static int
fd_read(BIO *b, char *out, int outl)
{
int ret = 0;
if (out != NULL) {
errno = 0;
ret = read(b->num, out, outl);
BIO_clear_retry_flags(b);
if (ret <= 0) {
if (BIO_fd_should_retry(ret))
BIO_set_retry_read(b);
}
}
return (ret);
}
static int
fd_write(BIO *b, const char *in, int inl)
{
int ret;
errno = 0;
ret = write(b->num, in, inl);
BIO_clear_retry_flags(b);
if (ret <= 0) {
if (BIO_fd_should_retry(ret))
BIO_set_retry_write(b);
}
return (ret);
}
static long
fd_ctrl(BIO *b, int cmd, long num, void *ptr)
{
long ret = 1;
int *ip;
switch (cmd) {
case BIO_CTRL_RESET:
num = 0;
case BIO_C_FILE_SEEK:
ret = (long)lseek(b->num, num, 0);
break;
case BIO_C_FILE_TELL:
case BIO_CTRL_INFO:
ret = (long)lseek(b->num, 0, 1);
break;
case BIO_C_SET_FD:
fd_free(b);
b->num= *((int *)ptr);
b->shutdown = (int)num;
b->init = 1;
break;
case BIO_C_GET_FD:
if (b->init) {
ip = (int *)ptr;
if (ip != NULL)
*ip = b->num;
ret = b->num;
} else
ret = -1;
break;
case BIO_CTRL_GET_CLOSE:
ret = b->shutdown;
break;
case BIO_CTRL_SET_CLOSE:
b->shutdown = (int)num;
break;
case BIO_CTRL_PENDING:
case BIO_CTRL_WPENDING:
ret = 0;
break;
case BIO_CTRL_DUP:
case BIO_CTRL_FLUSH:
ret = 1;
break;
default:
ret = 0;
break;
}
return (ret);
}
static int
fd_puts(BIO *bp, const char *str)
{
int n, ret;
n = strlen(str);
ret = fd_write(bp, str, n);
return (ret);
}
static int
fd_gets(BIO *bp, char *buf, int size)
{
int ret = 0;
char *ptr = buf;
char *end = buf + size - 1;
while ((ptr < end) && (fd_read(bp, ptr, 1) > 0) && (ptr[0] != '\n'))
ptr++;
ptr[0] = '\0';
if (buf[0] != '\0')
ret = strlen(buf);
return (ret);
}
int
BIO_fd_should_retry(int i)
{
int err;
if ((i == 0) || (i == -1)) {
err = errno;
return (BIO_fd_non_fatal_error(err));
}
return (0);
}
int
BIO_fd_non_fatal_error(int err)
{
switch (err) {
case ENOTCONN:
case EINTR:
case EAGAIN:
case EINPROGRESS:
case EALREADY:
return (1);
default:
break;
}
return (0);
}

320
externals/libressl/crypto/bio/bss_file.c vendored Executable file
View File

@@ -0,0 +1,320 @@
/* $OpenBSD: bss_file.c,v 1.33 2018/05/30 00:23:04 tb Exp $ */
/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
* All rights reserved.
*
* This package is an SSL implementation written
* by Eric Young (eay@cryptsoft.com).
* The implementation was written so as to conform with Netscapes SSL.
*
* This library is free for commercial and non-commercial use as long as
* the following conditions are aheared to. The following conditions
* apply to all code found in this distribution, be it the RC4, RSA,
* lhash, DES, etc., code; not just the SSL code. The SSL documentation
* included with this distribution is covered by the same copyright terms
* except that the holder is Tim Hudson (tjh@cryptsoft.com).
*
* Copyright remains Eric Young's, and as such any Copyright notices in
* the code are not to be removed.
* If this package is used in a product, Eric Young should be given attribution
* as the author of the parts of the library used.
* This can be in the form of a textual message at program startup or
* in documentation (online or textual) provided with the package.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* "This product includes cryptographic software written by
* Eric Young (eay@cryptsoft.com)"
* The word 'cryptographic' can be left out if the rouines from the library
* being used are not cryptographic related :-).
* 4. If you include any Windows specific code (or a derivative thereof) from
* the apps directory (application code) you must include an acknowledgement:
* "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
*
* THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* The licence and distribution terms for any publically available version or
* derivative of this code cannot be changed. i.e. this code cannot simply be
* copied and put under another distribution licence
* [including the GNU Public Licence.]
*/
/*
* 03-Dec-1997 rdenny@dc3.com Fix bug preventing use of stdin/stdout
* with binary data (e.g. asn1parse -inform DER < xxx) under
* Windows
*/
#ifndef HEADER_BSS_FILE_C
#define HEADER_BSS_FILE_C
#if defined(__linux) || defined(__sun) || defined(__hpux)
/* Following definition aliases fopen to fopen64 on above mentioned
* platforms. This makes it possible to open and sequentially access
* files larger than 2GB from 32-bit application. It does not allow to
* traverse them beyond 2GB with fseek/ftell, but on the other hand *no*
* 32-bit platform permits that, not with fseek/ftell. Not to mention
* that breaking 2GB limit for seeking would require surgery to *our*
* API. But sequential access suffices for practical cases when you
* can run into large files, such as fingerprinting, so we can let API
* alone. For reference, the list of 32-bit platforms which allow for
* sequential access of large files without extra "magic" comprise *BSD,
* Darwin, IRIX...
*/
#ifndef _FILE_OFFSET_BITS
#define _FILE_OFFSET_BITS 64
#endif
#endif
#include <errno.h>
#include <stdio.h>
#include <string.h>
#include <openssl/bio.h>
#include <openssl/err.h>
static int file_write(BIO *h, const char *buf, int num);
static int file_read(BIO *h, char *buf, int size);
static int file_puts(BIO *h, const char *str);
static int file_gets(BIO *h, char *str, int size);
static long file_ctrl(BIO *h, int cmd, long arg1, void *arg2);
static int file_new(BIO *h);
static int file_free(BIO *data);
static const BIO_METHOD methods_filep = {
.type = BIO_TYPE_FILE,
.name = "FILE pointer",
.bwrite = file_write,
.bread = file_read,
.bputs = file_puts,
.bgets = file_gets,
.ctrl = file_ctrl,
.create = file_new,
.destroy = file_free
};
BIO *
BIO_new_file(const char *filename, const char *mode)
{
BIO *ret;
FILE *file = NULL;
file = fopen(filename, mode);
if (file == NULL) {
SYSerror(errno);
ERR_asprintf_error_data("fopen('%s', '%s')", filename, mode);
if (errno == ENOENT)
BIOerror(BIO_R_NO_SUCH_FILE);
else
BIOerror(ERR_R_SYS_LIB);
return (NULL);
}
if ((ret = BIO_new(BIO_s_file())) == NULL) {
fclose(file);
return (NULL);
}
BIO_set_fp(ret, file, BIO_CLOSE);
return (ret);
}
BIO *
BIO_new_fp(FILE *stream, int close_flag)
{
BIO *ret;
if ((ret = BIO_new(BIO_s_file())) == NULL)
return (NULL);
BIO_set_fp(ret, stream, close_flag);
return (ret);
}
const BIO_METHOD *
BIO_s_file(void)
{
return (&methods_filep);
}
static int
file_new(BIO *bi)
{
bi->init = 0;
bi->num = 0;
bi->ptr = NULL;
bi->flags=0;
return (1);
}
static int
file_free(BIO *a)
{
if (a == NULL)
return (0);
if (a->shutdown) {
if ((a->init) && (a->ptr != NULL)) {
fclose (a->ptr);
a->ptr = NULL;
a->flags = 0;
}
a->init = 0;
}
return (1);
}
static int
file_read(BIO *b, char *out, int outl)
{
int ret = 0;
if (b->init && out != NULL) {
ret = fread(out, 1, outl, (FILE *)b->ptr);
if (ret == 0 && ferror((FILE *)b->ptr)) {
SYSerror(errno);
BIOerror(ERR_R_SYS_LIB);
ret = -1;
}
}
return (ret);
}
static int
file_write(BIO *b, const char *in, int inl)
{
int ret = 0;
if (b->init && in != NULL)
ret = fwrite(in, 1, inl, (FILE *)b->ptr);
return (ret);
}
static long
file_ctrl(BIO *b, int cmd, long num, void *ptr)
{
long ret = 1;
FILE *fp = (FILE *)b->ptr;
FILE **fpp;
char p[4];
switch (cmd) {
case BIO_C_FILE_SEEK:
case BIO_CTRL_RESET:
ret = (long)fseek(fp, num, 0);
break;
case BIO_CTRL_EOF:
ret = (long)feof(fp);
break;
case BIO_C_FILE_TELL:
case BIO_CTRL_INFO:
ret = ftell(fp);
break;
case BIO_C_SET_FILE_PTR:
file_free(b);
b->shutdown = (int)num&BIO_CLOSE;
b->ptr = ptr;
b->init = 1;
break;
case BIO_C_SET_FILENAME:
file_free(b);
b->shutdown = (int)num&BIO_CLOSE;
if (num & BIO_FP_APPEND) {
if (num & BIO_FP_READ)
strlcpy(p, "a+", sizeof p);
else strlcpy(p, "a", sizeof p);
} else if ((num & BIO_FP_READ) && (num & BIO_FP_WRITE))
strlcpy(p, "r+", sizeof p);
else if (num & BIO_FP_WRITE)
strlcpy(p, "w", sizeof p);
else if (num & BIO_FP_READ)
strlcpy(p, "r", sizeof p);
else {
BIOerror(BIO_R_BAD_FOPEN_MODE);
ret = 0;
break;
}
fp = fopen(ptr, p);
if (fp == NULL) {
SYSerror(errno);
ERR_asprintf_error_data("fopen('%s', '%s')", ptr, p);
BIOerror(ERR_R_SYS_LIB);
ret = 0;
break;
}
b->ptr = fp;
b->init = 1;
break;
case BIO_C_GET_FILE_PTR:
/* the ptr parameter is actually a FILE ** in this case. */
if (ptr != NULL) {
fpp = (FILE **)ptr;
*fpp = (FILE *)b->ptr;
}
break;
case BIO_CTRL_GET_CLOSE:
ret = (long)b->shutdown;
break;
case BIO_CTRL_SET_CLOSE:
b->shutdown = (int)num;
break;
case BIO_CTRL_FLUSH:
fflush((FILE *)b->ptr);
break;
case BIO_CTRL_DUP:
ret = 1;
break;
case BIO_CTRL_WPENDING:
case BIO_CTRL_PENDING:
case BIO_CTRL_PUSH:
case BIO_CTRL_POP:
default:
ret = 0;
break;
}
return (ret);
}
static int
file_gets(BIO *bp, char *buf, int size)
{
int ret = 0;
buf[0] = '\0';
if (!fgets(buf, size,(FILE *)bp->ptr))
goto err;
if (buf[0] != '\0')
ret = strlen(buf);
err:
return (ret);
}
static int
file_puts(BIO *bp, const char *str)
{
int n, ret;
n = strlen(str);
ret = file_write(bp, str, n);
return (ret);
}
#endif /* HEADER_BSS_FILE_C */

213
externals/libressl/crypto/bio/bss_log.c vendored Executable file
View File

@@ -0,0 +1,213 @@
/* $OpenBSD: bss_log.c,v 1.22 2018/05/01 13:29:10 tb Exp $ */
/* ====================================================================
* Copyright (c) 1999 The OpenSSL Project. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. All advertising materials mentioning features or use of this
* software must display the following acknowledgment:
* "This product includes software developed by the OpenSSL Project
* for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
*
* 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
* endorse or promote products derived from this software without
* prior written permission. For written permission, please contact
* licensing@OpenSSL.org.
*
* 5. Products derived from this software may not be called "OpenSSL"
* nor may "OpenSSL" appear in their names without prior written
* permission of the OpenSSL Project.
*
* 6. Redistributions of any form whatsoever must retain the following
* acknowledgment:
* "This product includes software developed by the OpenSSL Project
* for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
*
* THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
* EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
* OF THE POSSIBILITY OF SUCH DAMAGE.
* ====================================================================
*
* This product includes cryptographic software written by Eric Young
* (eay@cryptsoft.com). This product includes software written by Tim
* Hudson (tjh@cryptsoft.com).
*
*/
/*
Why BIO_s_log?
BIO_s_log is useful for system daemons (or services under NT).
It is one-way BIO, it sends all stuff to syslogd (on system that
commonly use that), or event log (on NT), or OPCOM (on OpenVMS).
*/
#include <errno.h>
#include <stdio.h>
#include <string.h>
#include <syslog.h>
#include <openssl/buffer.h>
#include <openssl/err.h>
#ifndef NO_SYSLOG
static int slg_write(BIO *h, const char *buf, int num);
static int slg_puts(BIO *h, const char *str);
static long slg_ctrl(BIO *h, int cmd, long arg1, void *arg2);
static int slg_new(BIO *h);
static int slg_free(BIO *data);
static void xopenlog(BIO* bp, char* name, int level);
static void xsyslog(BIO* bp, int priority, const char* string);
static void xcloselog(BIO* bp);
static const BIO_METHOD methods_slg = {
.type = BIO_TYPE_MEM,
.name = "syslog",
.bwrite = slg_write,
.bputs = slg_puts,
.ctrl = slg_ctrl,
.create = slg_new,
.destroy = slg_free
};
const BIO_METHOD *
BIO_s_log(void)
{
return (&methods_slg);
}
static int
slg_new(BIO *bi)
{
bi->init = 1;
bi->num = 0;
bi->ptr = NULL;
xopenlog(bi, "application", LOG_DAEMON);
return (1);
}
static int
slg_free(BIO *a)
{
if (a == NULL)
return (0);
xcloselog(a);
return (1);
}
static int
slg_write(BIO *b, const char *in, int inl)
{
int ret = inl;
char* buf;
char* pp;
int priority, i;
static const struct {
int strl;
char str[10];
int log_level;
}
mapping[] = {
{ 6, "PANIC ", LOG_EMERG },
{ 6, "EMERG ", LOG_EMERG },
{ 4, "EMR ", LOG_EMERG },
{ 6, "ALERT ", LOG_ALERT },
{ 4, "ALR ", LOG_ALERT },
{ 5, "CRIT ", LOG_CRIT },
{ 4, "CRI ", LOG_CRIT },
{ 6, "ERROR ", LOG_ERR },
{ 4, "ERR ", LOG_ERR },
{ 8, "WARNING ", LOG_WARNING },
{ 5, "WARN ", LOG_WARNING },
{ 4, "WAR ", LOG_WARNING },
{ 7, "NOTICE ", LOG_NOTICE },
{ 5, "NOTE ", LOG_NOTICE },
{ 4, "NOT ", LOG_NOTICE },
{ 5, "INFO ", LOG_INFO },
{ 4, "INF ", LOG_INFO },
{ 6, "DEBUG ", LOG_DEBUG },
{ 4, "DBG ", LOG_DEBUG },
{ 0, "", LOG_ERR } /* The default */
};
if ((buf = malloc(inl + 1)) == NULL) {
return (0);
}
strlcpy(buf, in, inl + 1);
i = 0;
while (strncmp(buf, mapping[i].str, mapping[i].strl) != 0)
i++;
priority = mapping[i].log_level;
pp = buf + mapping[i].strl;
xsyslog(b, priority, pp);
free(buf);
return (ret);
}
static long
slg_ctrl(BIO *b, int cmd, long num, void *ptr)
{
switch (cmd) {
case BIO_CTRL_SET:
xcloselog(b);
xopenlog(b, ptr, num);
break;
default:
break;
}
return (0);
}
static int
slg_puts(BIO *bp, const char *str)
{
int n, ret;
n = strlen(str);
ret = slg_write(bp, str, n);
return (ret);
}
static void
xopenlog(BIO* bp, char* name, int level)
{
openlog(name, LOG_PID|LOG_CONS, level);
}
static void
xsyslog(BIO *bp, int priority, const char *string)
{
syslog(priority, "%s", string);
}
static void
xcloselog(BIO* bp)
{
closelog();
}
#endif /* NO_SYSLOG */

321
externals/libressl/crypto/bio/bss_mem.c vendored Executable file
View File

@@ -0,0 +1,321 @@
/* $OpenBSD: bss_mem.c,v 1.17 2018/05/12 18:51:59 tb Exp $ */
/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
* All rights reserved.
*
* This package is an SSL implementation written
* by Eric Young (eay@cryptsoft.com).
* The implementation was written so as to conform with Netscapes SSL.
*
* This library is free for commercial and non-commercial use as long as
* the following conditions are aheared to. The following conditions
* apply to all code found in this distribution, be it the RC4, RSA,
* lhash, DES, etc., code; not just the SSL code. The SSL documentation
* included with this distribution is covered by the same copyright terms
* except that the holder is Tim Hudson (tjh@cryptsoft.com).
*
* Copyright remains Eric Young's, and as such any Copyright notices in
* the code are not to be removed.
* If this package is used in a product, Eric Young should be given attribution
* as the author of the parts of the library used.
* This can be in the form of a textual message at program startup or
* in documentation (online or textual) provided with the package.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* "This product includes cryptographic software written by
* Eric Young (eay@cryptsoft.com)"
* The word 'cryptographic' can be left out if the rouines from the library
* being used are not cryptographic related :-).
* 4. If you include any Windows specific code (or a derivative thereof) from
* the apps directory (application code) you must include an acknowledgement:
* "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
*
* THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* The licence and distribution terms for any publically available version or
* derivative of this code cannot be changed. i.e. this code cannot simply be
* copied and put under another distribution licence
* [including the GNU Public Licence.]
*/
#include <errno.h>
#include <stdio.h>
#include <string.h>
#include <openssl/bio.h>
#include <openssl/err.h>
#include <openssl/buffer.h>
static int mem_write(BIO *h, const char *buf, int num);
static int mem_read(BIO *h, char *buf, int size);
static int mem_puts(BIO *h, const char *str);
static int mem_gets(BIO *h, char *str, int size);
static long mem_ctrl(BIO *h, int cmd, long arg1, void *arg2);
static int mem_new(BIO *h);
static int mem_free(BIO *data);
static const BIO_METHOD mem_method = {
.type = BIO_TYPE_MEM,
.name = "memory buffer",
.bwrite = mem_write,
.bread = mem_read,
.bputs = mem_puts,
.bgets = mem_gets,
.ctrl = mem_ctrl,
.create = mem_new,
.destroy = mem_free
};
/* bio->num is used to hold the value to return on 'empty', if it is
* 0, should_retry is not set */
const BIO_METHOD *
BIO_s_mem(void)
{
return (&mem_method);
}
BIO *
BIO_new_mem_buf(const void *buf, int len)
{
BIO *ret;
BUF_MEM *b;
size_t sz;
if (!buf) {
BIOerror(BIO_R_NULL_PARAMETER);
return NULL;
}
sz = (len < 0) ? strlen(buf) : (size_t)len;
if (!(ret = BIO_new(BIO_s_mem())))
return NULL;
b = (BUF_MEM *)ret->ptr;
b->data = (void *)buf; /* Trust in the BIO_FLAGS_MEM_RDONLY flag. */
b->length = sz;
b->max = sz;
ret->flags |= BIO_FLAGS_MEM_RDONLY;
/* Since this is static data retrying wont help */
ret->num = 0;
return ret;
}
static int
mem_new(BIO *bi)
{
BUF_MEM *b;
if ((b = BUF_MEM_new()) == NULL)
return (0);
bi->shutdown = 1;
bi->init = 1;
bi->num = -1;
bi->ptr = (char *)b;
return (1);
}
static int
mem_free(BIO *a)
{
if (a == NULL)
return (0);
if (a->shutdown) {
if ((a->init) && (a->ptr != NULL)) {
BUF_MEM *b;
b = (BUF_MEM *)a->ptr;
if (a->flags & BIO_FLAGS_MEM_RDONLY)
b->data = NULL;
BUF_MEM_free(b);
a->ptr = NULL;
}
}
return (1);
}
static int
mem_read(BIO *b, char *out, int outl)
{
int ret = -1;
BUF_MEM *bm;
bm = (BUF_MEM *)b->ptr;
BIO_clear_retry_flags(b);
ret = (outl >=0 && (size_t)outl > bm->length) ? (int)bm->length : outl;
if ((out != NULL) && (ret > 0)) {
memcpy(out, bm->data, ret);
bm->length -= ret;
if (b->flags & BIO_FLAGS_MEM_RDONLY)
bm->data += ret;
else {
memmove(&(bm->data[0]), &(bm->data[ret]), bm->length);
}
} else if (bm->length == 0) {
ret = b->num;
if (ret != 0)
BIO_set_retry_read(b);
}
return (ret);
}
static int
mem_write(BIO *b, const char *in, int inl)
{
int ret = -1;
int blen;
BUF_MEM *bm;
bm = (BUF_MEM *)b->ptr;
if (in == NULL) {
BIOerror(BIO_R_NULL_PARAMETER);
goto end;
}
if (b->flags & BIO_FLAGS_MEM_RDONLY) {
BIOerror(BIO_R_WRITE_TO_READ_ONLY_BIO);
goto end;
}
BIO_clear_retry_flags(b);
blen = bm->length;
if (BUF_MEM_grow_clean(bm, blen + inl) != (blen + inl))
goto end;
memcpy(&(bm->data[blen]), in, inl);
ret = inl;
end:
return (ret);
}
static long
mem_ctrl(BIO *b, int cmd, long num, void *ptr)
{
long ret = 1;
char **pptr;
BUF_MEM *bm = (BUF_MEM *)b->ptr;
switch (cmd) {
case BIO_CTRL_RESET:
if (bm->data != NULL) {
/* For read only case reset to the start again */
if (b->flags & BIO_FLAGS_MEM_RDONLY) {
bm->data -= bm->max - bm->length;
bm->length = bm->max;
} else {
memset(bm->data, 0, bm->max);
bm->length = 0;
}
}
break;
case BIO_CTRL_EOF:
ret = (long)(bm->length == 0);
break;
case BIO_C_SET_BUF_MEM_EOF_RETURN:
b->num = (int)num;
break;
case BIO_CTRL_INFO:
ret = (long)bm->length;
if (ptr != NULL) {
pptr = (char **)ptr;
*pptr = (char *)&(bm->data[0]);
}
break;
case BIO_C_SET_BUF_MEM:
mem_free(b);
b->shutdown = (int)num;
b->ptr = ptr;
break;
case BIO_C_GET_BUF_MEM_PTR:
if (ptr != NULL) {
pptr = (char **)ptr;
*pptr = (char *)bm;
}
break;
case BIO_CTRL_GET_CLOSE:
ret = (long)b->shutdown;
break;
case BIO_CTRL_SET_CLOSE:
b->shutdown = (int)num;
break;
case BIO_CTRL_WPENDING:
ret = 0L;
break;
case BIO_CTRL_PENDING:
ret = (long)bm->length;
break;
case BIO_CTRL_DUP:
case BIO_CTRL_FLUSH:
ret = 1;
break;
case BIO_CTRL_PUSH:
case BIO_CTRL_POP:
default:
ret = 0;
break;
}
return (ret);
}
static int
mem_gets(BIO *bp, char *buf, int size)
{
int i, j;
int ret = -1;
char *p;
BUF_MEM *bm = (BUF_MEM *)bp->ptr;
BIO_clear_retry_flags(bp);
j = bm->length;
if ((size - 1) < j)
j = size - 1;
if (j <= 0) {
*buf = '\0';
return 0;
}
p = bm->data;
for (i = 0; i < j; i++) {
if (p[i] == '\n') {
i++;
break;
}
}
/*
* i is now the max num of bytes to copy, either j or up to
* and including the first newline
*/
i = mem_read(bp, buf, i);
if (i > 0)
buf[i] = '\0';
ret = i;
return (ret);
}
static int
mem_puts(BIO *bp, const char *str)
{
int n, ret;
n = strlen(str);
ret = mem_write(bp, str, n);
/* memory semantics is that it will always work */
return (ret);
}

158
externals/libressl/crypto/bio/bss_null.c vendored Executable file
View File

@@ -0,0 +1,158 @@
/* $OpenBSD: bss_null.c,v 1.11 2018/05/01 13:29:10 tb Exp $ */
/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
* All rights reserved.
*
* This package is an SSL implementation written
* by Eric Young (eay@cryptsoft.com).
* The implementation was written so as to conform with Netscapes SSL.
*
* This library is free for commercial and non-commercial use as long as
* the following conditions are aheared to. The following conditions
* apply to all code found in this distribution, be it the RC4, RSA,
* lhash, DES, etc., code; not just the SSL code. The SSL documentation
* included with this distribution is covered by the same copyright terms
* except that the holder is Tim Hudson (tjh@cryptsoft.com).
*
* Copyright remains Eric Young's, and as such any Copyright notices in
* the code are not to be removed.
* If this package is used in a product, Eric Young should be given attribution
* as the author of the parts of the library used.
* This can be in the form of a textual message at program startup or
* in documentation (online or textual) provided with the package.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* "This product includes cryptographic software written by
* Eric Young (eay@cryptsoft.com)"
* The word 'cryptographic' can be left out if the rouines from the library
* being used are not cryptographic related :-).
* 4. If you include any Windows specific code (or a derivative thereof) from
* the apps directory (application code) you must include an acknowledgement:
* "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
*
* THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* The licence and distribution terms for any publically available version or
* derivative of this code cannot be changed. i.e. this code cannot simply be
* copied and put under another distribution licence
* [including the GNU Public Licence.]
*/
#include <errno.h>
#include <stdio.h>
#include <string.h>
#include <openssl/bio.h>
static int null_write(BIO *h, const char *buf, int num);
static int null_read(BIO *h, char *buf, int size);
static int null_puts(BIO *h, const char *str);
static int null_gets(BIO *h, char *str, int size);
static long null_ctrl(BIO *h, int cmd, long arg1, void *arg2);
static int null_new(BIO *h);
static int null_free(BIO *data);
static const BIO_METHOD null_method = {
.type = BIO_TYPE_NULL,
.name = "NULL",
.bwrite = null_write,
.bread = null_read,
.bputs = null_puts,
.bgets = null_gets,
.ctrl = null_ctrl,
.create = null_new,
.destroy = null_free
};
const BIO_METHOD *
BIO_s_null(void)
{
return (&null_method);
}
static int
null_new(BIO *bi)
{
bi->init = 1;
bi->num = 0;
bi->ptr = (NULL);
return (1);
}
static int
null_free(BIO *a)
{
if (a == NULL)
return (0);
return (1);
}
static int
null_read(BIO *b, char *out, int outl)
{
return (0);
}
static int
null_write(BIO *b, const char *in, int inl)
{
return (inl);
}
static long
null_ctrl(BIO *b, int cmd, long num, void *ptr)
{
long ret = 1;
switch (cmd) {
case BIO_CTRL_RESET:
case BIO_CTRL_EOF:
case BIO_CTRL_SET:
case BIO_CTRL_SET_CLOSE:
case BIO_CTRL_FLUSH:
case BIO_CTRL_DUP:
ret = 1;
break;
case BIO_CTRL_GET_CLOSE:
case BIO_CTRL_INFO:
case BIO_CTRL_GET:
case BIO_CTRL_PENDING:
case BIO_CTRL_WPENDING:
default:
ret = 0;
break;
}
return (ret);
}
static int
null_gets(BIO *bp, char *buf, int size)
{
return (0);
}
static int
null_puts(BIO *bp, const char *str)
{
if (str == NULL)
return (0);
return (strlen(str));
}

239
externals/libressl/crypto/bio/bss_sock.c vendored Executable file
View File

@@ -0,0 +1,239 @@
/* $OpenBSD: bss_sock.c,v 1.24 2018/05/01 13:29:10 tb Exp $ */
/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
* All rights reserved.
*
* This package is an SSL implementation written
* by Eric Young (eay@cryptsoft.com).
* The implementation was written so as to conform with Netscapes SSL.
*
* This library is free for commercial and non-commercial use as long as
* the following conditions are aheared to. The following conditions
* apply to all code found in this distribution, be it the RC4, RSA,
* lhash, DES, etc., code; not just the SSL code. The SSL documentation
* included with this distribution is covered by the same copyright terms
* except that the holder is Tim Hudson (tjh@cryptsoft.com).
*
* Copyright remains Eric Young's, and as such any Copyright notices in
* the code are not to be removed.
* If this package is used in a product, Eric Young should be given attribution
* as the author of the parts of the library used.
* This can be in the form of a textual message at program startup or
* in documentation (online or textual) provided with the package.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* "This product includes cryptographic software written by
* Eric Young (eay@cryptsoft.com)"
* The word 'cryptographic' can be left out if the rouines from the library
* being used are not cryptographic related :-).
* 4. If you include any Windows specific code (or a derivative thereof) from
* the apps directory (application code) you must include an acknowledgement:
* "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
*
* THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* The licence and distribution terms for any publically available version or
* derivative of this code cannot be changed. i.e. this code cannot simply be
* copied and put under another distribution licence
* [including the GNU Public Licence.]
*/
#include <sys/socket.h>
#include <errno.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <openssl/bio.h>
static int sock_write(BIO *h, const char *buf, int num);
static int sock_read(BIO *h, char *buf, int size);
static int sock_puts(BIO *h, const char *str);
static long sock_ctrl(BIO *h, int cmd, long arg1, void *arg2);
static int sock_new(BIO *h);
static int sock_free(BIO *data);
int BIO_sock_should_retry(int s);
static const BIO_METHOD methods_sockp = {
.type = BIO_TYPE_SOCKET,
.name = "socket",
.bwrite = sock_write,
.bread = sock_read,
.bputs = sock_puts,
.ctrl = sock_ctrl,
.create = sock_new,
.destroy = sock_free
};
const BIO_METHOD *
BIO_s_socket(void)
{
return (&methods_sockp);
}
BIO *
BIO_new_socket(int fd, int close_flag)
{
BIO *ret;
ret = BIO_new(BIO_s_socket());
if (ret == NULL)
return (NULL);
BIO_set_fd(ret, fd, close_flag);
return (ret);
}
static int
sock_new(BIO *bi)
{
bi->init = 0;
bi->num = 0;
bi->ptr = NULL;
bi->flags = 0;
return (1);
}
static int
sock_free(BIO *a)
{
if (a == NULL)
return (0);
if (a->shutdown) {
if (a->init) {
shutdown(a->num, SHUT_RDWR);
close(a->num);
}
a->init = 0;
a->flags = 0;
}
return (1);
}
static int
sock_read(BIO *b, char *out, int outl)
{
int ret = 0;
if (out != NULL) {
errno = 0;
ret = read(b->num, out, outl);
BIO_clear_retry_flags(b);
if (ret <= 0) {
if (BIO_sock_should_retry(ret))
BIO_set_retry_read(b);
}
}
return (ret);
}
static int
sock_write(BIO *b, const char *in, int inl)
{
int ret;
errno = 0;
ret = write(b->num, in, inl);
BIO_clear_retry_flags(b);
if (ret <= 0) {
if (BIO_sock_should_retry(ret))
BIO_set_retry_write(b);
}
return (ret);
}
static long
sock_ctrl(BIO *b, int cmd, long num, void *ptr)
{
long ret = 1;
int *ip;
switch (cmd) {
case BIO_C_SET_FD:
sock_free(b);
b->num= *((int *)ptr);
b->shutdown = (int)num;
b->init = 1;
break;
case BIO_C_GET_FD:
if (b->init) {
ip = (int *)ptr;
if (ip != NULL)
*ip = b->num;
ret = b->num;
} else
ret = -1;
break;
case BIO_CTRL_GET_CLOSE:
ret = b->shutdown;
break;
case BIO_CTRL_SET_CLOSE:
b->shutdown = (int)num;
break;
case BIO_CTRL_DUP:
case BIO_CTRL_FLUSH:
ret = 1;
break;
default:
ret = 0;
break;
}
return (ret);
}
static int
sock_puts(BIO *bp, const char *str)
{
int n, ret;
n = strlen(str);
ret = sock_write(bp, str, n);
return (ret);
}
int
BIO_sock_should_retry(int i)
{
int err;
if ((i == 0) || (i == -1)) {
err = errno;
return (BIO_sock_non_fatal_error(err));
}
return (0);
}
int
BIO_sock_non_fatal_error(int err)
{
switch (err) {
case ENOTCONN:
case EINTR:
case EAGAIN:
case EINPROGRESS:
case EALREADY:
return (1);
default:
break;
}
return (0);
}