Imported Upstream version 4.8.0.309

Former-commit-id: 5f9c6ae75f295e057a7d2971f3a6df4656fa8850
This commit is contained in:
Xamarin Public Jenkins (auto-signing)
2016-11-10 13:04:39 +00:00
parent ee1447783b
commit 94b2861243
4912 changed files with 390737 additions and 49310 deletions

View File

@@ -0,0 +1,35 @@
include_directories(../../include)
add_library(
bio
OBJECT
bio.c
bio_mem.c
buffer.c
connect.c
fd.c
file.c
hexdump.c
pair.c
printf.c
socket.c
socket_helper.c
)
if(ENABLE_TESTS)
add_executable(
bio_test
bio_test.cc
$<TARGET_OBJECTS:test_support>
)
target_link_libraries(bio_test crypto)
if (WIN32)
target_link_libraries(bio_test ws2_32)
endif()
add_dependencies(all_tests bio_test)
endif()

608
external/boringssl/crypto/bio/bio.c vendored Normal file

File diff suppressed because it is too large Load Diff

328
external/boringssl/crypto/bio/bio_mem.c vendored Normal file
View File

@@ -0,0 +1,328 @@
/* 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 <openssl/bio.h>
#include <limits.h>
#include <string.h>
#include <openssl/buf.h>
#include <openssl/err.h>
#include <openssl/mem.h>
BIO *BIO_new_mem_buf(const void *buf, int len) {
BIO *ret;
BUF_MEM *b;
const size_t size = len < 0 ? strlen((char *)buf) : (size_t)len;
if (!buf && len != 0) {
OPENSSL_PUT_ERROR(BIO, BIO_R_NULL_PARAMETER);
return NULL;
}
ret = BIO_new(BIO_s_mem());
if (ret == NULL) {
return NULL;
}
b = (BUF_MEM *)ret->ptr;
/* BIO_FLAGS_MEM_RDONLY ensures |b->data| is not written to. */
b->data = (void *)buf;
b->length = size;
b->max = size;
ret->flags |= BIO_FLAGS_MEM_RDONLY;
/* |num| is used to store the value that this BIO will return when it runs
* out of data. If it's negative then the retry flags will also be set. Since
* this is static data, retrying wont help */
ret->num = 0;
return ret;
}
static int mem_new(BIO *bio) {
BUF_MEM *b;
b = BUF_MEM_new();
if (b == NULL) {
return 0;
}
/* |shutdown| is used to store the close flag: whether the BIO has ownership
* of the BUF_MEM. */
bio->shutdown = 1;
bio->init = 1;
bio->num = -1;
bio->ptr = (char *)b;
return 1;
}
static int mem_free(BIO *bio) {
BUF_MEM *b;
if (bio == NULL) {
return 0;
}
if (!bio->shutdown || !bio->init || bio->ptr == NULL) {
return 1;
}
b = (BUF_MEM *)bio->ptr;
if (bio->flags & BIO_FLAGS_MEM_RDONLY) {
b->data = NULL;
}
BUF_MEM_free(b);
bio->ptr = NULL;
return 1;
}
static int mem_read(BIO *bio, char *out, int outl) {
int ret;
BUF_MEM *b = (BUF_MEM*) bio->ptr;
BIO_clear_retry_flags(bio);
ret = outl;
if (b->length < INT_MAX && ret > (int)b->length) {
ret = b->length;
}
if (ret > 0) {
memcpy(out, b->data, ret);
b->length -= ret;
if (bio->flags & BIO_FLAGS_MEM_RDONLY) {
b->data += ret;
} else {
memmove(b->data, &b->data[ret], b->length);
}
} else if (b->length == 0) {
ret = bio->num;
if (ret != 0) {
BIO_set_retry_read(bio);
}
}
return ret;
}
static int mem_write(BIO *bio, const char *in, int inl) {
int ret = -1;
int blen;
BUF_MEM *b;
b = (BUF_MEM *)bio->ptr;
if (bio->flags & BIO_FLAGS_MEM_RDONLY) {
OPENSSL_PUT_ERROR(BIO, BIO_R_WRITE_TO_READ_ONLY_BIO);
goto err;
}
BIO_clear_retry_flags(bio);
blen = b->length;
if (INT_MAX - blen < inl) {
goto err;
}
if (BUF_MEM_grow_clean(b, blen + inl) != ((size_t) blen) + inl) {
goto err;
}
memcpy(&b->data[blen], in, inl);
ret = inl;
err:
return ret;
}
static int mem_puts(BIO *bp, const char *str) {
return mem_write(bp, str, strlen(str));
}
static int mem_gets(BIO *bio, char *buf, int size) {
int i, j;
char *p;
BUF_MEM *b = (BUF_MEM *)bio->ptr;
BIO_clear_retry_flags(bio);
j = b->length;
if (size - 1 < j) {
j = size - 1;
}
if (j <= 0) {
if (size > 0) {
*buf = 0;
}
return 0;
}
p = b->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(bio, buf, i);
if (i > 0) {
buf[i] = '\0';
}
return i;
}
static long mem_ctrl(BIO *bio, int cmd, long num, void *ptr) {
long ret = 1;
char **pptr;
BUF_MEM *b = (BUF_MEM *)bio->ptr;
switch (cmd) {
case BIO_CTRL_RESET:
if (b->data != NULL) {
/* For read only case reset to the start again */
if (bio->flags & BIO_FLAGS_MEM_RDONLY) {
b->data -= b->max - b->length;
b->length = b->max;
} else {
memset(b->data, 0, b->max);
b->length = 0;
}
}
break;
case BIO_CTRL_EOF:
ret = (long)(b->length == 0);
break;
case BIO_C_SET_BUF_MEM_EOF_RETURN:
bio->num = (int)num;
break;
case BIO_CTRL_INFO:
ret = (long)b->length;
if (ptr != NULL) {
pptr = (char **)ptr;
*pptr = (char *)&b->data[0];
}
break;
case BIO_C_SET_BUF_MEM:
mem_free(bio);
bio->shutdown = (int)num;
bio->ptr = ptr;
break;
case BIO_C_GET_BUF_MEM_PTR:
if (ptr != NULL) {
pptr = (char **)ptr;
*pptr = (char *)b;
}
break;
case BIO_CTRL_GET_CLOSE:
ret = (long)bio->shutdown;
break;
case BIO_CTRL_SET_CLOSE:
bio->shutdown = (int)num;
break;
case BIO_CTRL_WPENDING:
ret = 0L;
break;
case BIO_CTRL_PENDING:
ret = (long)b->length;
break;
case BIO_CTRL_FLUSH:
ret = 1;
break;
default:
ret = 0;
break;
}
return ret;
}
static const BIO_METHOD mem_method = {
BIO_TYPE_MEM, "memory buffer", mem_write, mem_read, mem_puts,
mem_gets, mem_ctrl, mem_new, mem_free, NULL, };
const BIO_METHOD *BIO_s_mem(void) { return &mem_method; }
int BIO_mem_contents(const BIO *bio, const uint8_t **out_contents,
size_t *out_len) {
const BUF_MEM *b;
if (bio->method != &mem_method) {
return 0;
}
b = (BUF_MEM *)bio->ptr;
*out_contents = (uint8_t *)b->data;
*out_len = b->length;
return 1;
}
long BIO_get_mem_data(BIO *bio, char **contents) {
return BIO_ctrl(bio, BIO_CTRL_INFO, 0, (char *) contents);
}
int BIO_get_mem_ptr(BIO *bio, BUF_MEM **out) {
return BIO_ctrl(bio, BIO_C_GET_BUF_MEM_PTR, 0, (char *) out);
}
int BIO_set_mem_buf(BIO *bio, BUF_MEM *b, int take_ownership) {
return BIO_ctrl(bio, BIO_C_SET_BUF_MEM, take_ownership, (char *) b);
}
int BIO_set_mem_eof_return(BIO *bio, int eof_value) {
return BIO_ctrl(bio, BIO_C_SET_BUF_MEM_EOF_RETURN, eof_value, NULL);
}

View File

@@ -0,0 +1,440 @@
/* Copyright (c) 2014, Google Inc.
*
* Permission to use, copy, modify, and/or 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. */
#if !defined(_POSIX_C_SOURCE)
#define _POSIX_C_SOURCE 201410L
#endif
#include <openssl/base.h>
#if !defined(OPENSSL_WINDOWS)
#include <arpa/inet.h>
#include <fcntl.h>
#include <netinet/in.h>
#include <string.h>
#include <sys/socket.h>
#include <unistd.h>
#else
#include <io.h>
OPENSSL_MSVC_PRAGMA(warning(push, 3))
#include <winsock2.h>
#include <ws2tcpip.h>
OPENSSL_MSVC_PRAGMA(warning(pop))
#endif
#include <openssl/bio.h>
#include <openssl/crypto.h>
#include <openssl/err.h>
#include <openssl/mem.h>
#include <algorithm>
#include "../test/scoped_types.h"
#if !defined(OPENSSL_WINDOWS)
static int closesocket(int sock) {
return close(sock);
}
static void PrintSocketError(const char *func) {
perror(func);
}
#else
static void PrintSocketError(const char *func) {
fprintf(stderr, "%s: %d\n", func, WSAGetLastError());
}
#endif
class ScopedSocket {
public:
ScopedSocket(int sock) : sock_(sock) {}
~ScopedSocket() {
closesocket(sock_);
}
private:
const int sock_;
};
static bool TestSocketConnect() {
static const char kTestMessage[] = "test";
int listening_sock = socket(AF_INET, SOCK_STREAM, 0);
if (listening_sock == -1) {
PrintSocketError("socket");
return false;
}
ScopedSocket listening_sock_closer(listening_sock);
struct sockaddr_in sin;
memset(&sin, 0, sizeof(sin));
sin.sin_family = AF_INET;
if (!inet_pton(AF_INET, "127.0.0.1", &sin.sin_addr)) {
PrintSocketError("inet_pton");
return false;
}
if (bind(listening_sock, (struct sockaddr *)&sin, sizeof(sin)) != 0) {
PrintSocketError("bind");
return false;
}
if (listen(listening_sock, 1)) {
PrintSocketError("listen");
return false;
}
socklen_t sockaddr_len = sizeof(sin);
if (getsockname(listening_sock, (struct sockaddr *)&sin, &sockaddr_len) ||
sockaddr_len != sizeof(sin)) {
PrintSocketError("getsockname");
return false;
}
char hostname[80];
BIO_snprintf(hostname, sizeof(hostname), "%s:%d", "127.0.0.1",
ntohs(sin.sin_port));
ScopedBIO bio(BIO_new_connect(hostname));
if (!bio) {
fprintf(stderr, "BIO_new_connect failed.\n");
return false;
}
if (BIO_write(bio.get(), kTestMessage, sizeof(kTestMessage)) !=
sizeof(kTestMessage)) {
fprintf(stderr, "BIO_write failed.\n");
ERR_print_errors_fp(stderr);
return false;
}
int sock = accept(listening_sock, (struct sockaddr *) &sin, &sockaddr_len);
if (sock == -1) {
PrintSocketError("accept");
return false;
}
ScopedSocket sock_closer(sock);
char buf[5];
if (recv(sock, buf, sizeof(buf), 0) != sizeof(kTestMessage)) {
PrintSocketError("read");
return false;
}
if (memcmp(buf, kTestMessage, sizeof(kTestMessage))) {
return false;
}
return true;
}
// BioReadZeroCopyWrapper is a wrapper around the zero-copy APIs to make
// testing easier.
static size_t BioReadZeroCopyWrapper(BIO *bio, uint8_t *data, size_t len) {
uint8_t *read_buf;
size_t read_buf_offset;
size_t available_bytes;
size_t len_read = 0;
do {
if (!BIO_zero_copy_get_read_buf(bio, &read_buf, &read_buf_offset,
&available_bytes)) {
return 0;
}
available_bytes = std::min(available_bytes, len - len_read);
memmove(data + len_read, read_buf + read_buf_offset, available_bytes);
BIO_zero_copy_get_read_buf_done(bio, available_bytes);
len_read += available_bytes;
} while (len - len_read > 0 && available_bytes > 0);
return len_read;
}
// BioWriteZeroCopyWrapper is a wrapper around the zero-copy APIs to make
// testing easier.
static size_t BioWriteZeroCopyWrapper(BIO *bio, const uint8_t *data,
size_t len) {
uint8_t *write_buf;
size_t write_buf_offset;
size_t available_bytes;
size_t len_written = 0;
do {
if (!BIO_zero_copy_get_write_buf(bio, &write_buf, &write_buf_offset,
&available_bytes)) {
return 0;
}
available_bytes = std::min(available_bytes, len - len_written);
memmove(write_buf + write_buf_offset, data + len_written, available_bytes);
BIO_zero_copy_get_write_buf_done(bio, available_bytes);
len_written += available_bytes;
} while (len - len_written > 0 && available_bytes > 0);
return len_written;
}
static bool TestZeroCopyBioPairs() {
// Test read and write, especially triggering the ring buffer wrap-around.
uint8_t bio1_application_send_buffer[1024];
uint8_t bio2_application_recv_buffer[1024];
const size_t kLengths[] = {254, 255, 256, 257, 510, 511, 512, 513};
// These trigger ring buffer wrap around.
const size_t kPartialLengths[] = {0, 1, 2, 3, 128, 255, 256, 257, 511, 512};
static const size_t kBufferSize = 512;
srand(1);
for (size_t i = 0; i < sizeof(bio1_application_send_buffer); i++) {
bio1_application_send_buffer[i] = rand() & 255;
}
// Transfer bytes from bio1_application_send_buffer to
// bio2_application_recv_buffer in various ways.
for (size_t i = 0; i < sizeof(kLengths) / sizeof(kLengths[0]); i++) {
for (size_t j = 0; j < sizeof(kPartialLengths) / sizeof(kPartialLengths[0]);
j++) {
size_t total_write = 0;
size_t total_read = 0;
BIO *bio1, *bio2;
if (!BIO_new_bio_pair(&bio1, kBufferSize, &bio2, kBufferSize)) {
return false;
}
ScopedBIO bio1_scoper(bio1);
ScopedBIO bio2_scoper(bio2);
total_write += BioWriteZeroCopyWrapper(
bio1, bio1_application_send_buffer, kLengths[i]);
// This tests interleaved read/write calls. Do a read between zero copy
// write calls.
uint8_t *write_buf;
size_t write_buf_offset;
size_t available_bytes;
if (!BIO_zero_copy_get_write_buf(bio1, &write_buf, &write_buf_offset,
&available_bytes)) {
return false;
}
// Free kPartialLengths[j] bytes in the beginning of bio1 write buffer.
// This enables ring buffer wrap around for the next write.
total_read += BIO_read(bio2, bio2_application_recv_buffer + total_read,
kPartialLengths[j]);
size_t interleaved_write_len = std::min(kPartialLengths[j],
available_bytes);
// Write the data for the interleaved write call. If the buffer becomes
// empty after a read, the write offset is normally set to 0. Check that
// this does not happen for interleaved read/write and that
// |write_buf_offset| is still valid.
memcpy(write_buf + write_buf_offset,
bio1_application_send_buffer + total_write, interleaved_write_len);
if (BIO_zero_copy_get_write_buf_done(bio1, interleaved_write_len)) {
total_write += interleaved_write_len;
}
// Do another write in case |write_buf_offset| was wrapped.
total_write += BioWriteZeroCopyWrapper(
bio1, bio1_application_send_buffer + total_write,
kPartialLengths[j] - interleaved_write_len);
// Drain the rest.
size_t bytes_left = BIO_pending(bio2);
total_read += BioReadZeroCopyWrapper(
bio2, bio2_application_recv_buffer + total_read, bytes_left);
if (total_read != total_write) {
fprintf(stderr, "Lengths not equal in round (%u, %u)\n", (unsigned)i,
(unsigned)j);
return false;
}
if (total_read > kLengths[i] + kPartialLengths[j]) {
fprintf(stderr, "Bad lengths in round (%u, %u)\n", (unsigned)i,
(unsigned)j);
return false;
}
if (memcmp(bio1_application_send_buffer, bio2_application_recv_buffer,
total_read) != 0) {
fprintf(stderr, "Buffers not equal in round (%u, %u)\n", (unsigned)i,
(unsigned)j);
return false;
}
}
}
return true;
}
static bool TestPrintf() {
// Test a short output, a very long one, and various sizes around
// 256 (the size of the buffer) to ensure edge cases are correct.
static const size_t kLengths[] = { 5, 250, 251, 252, 253, 254, 1023 };
ScopedBIO bio(BIO_new(BIO_s_mem()));
if (!bio) {
fprintf(stderr, "BIO_new failed\n");
return false;
}
for (size_t i = 0; i < sizeof(kLengths) / sizeof(kLengths[0]); i++) {
char string[1024];
if (kLengths[i] >= sizeof(string)) {
fprintf(stderr, "Bad test string length\n");
return false;
}
memset(string, 'a', sizeof(string));
string[kLengths[i]] = '\0';
int ret = BIO_printf(bio.get(), "test %s", string);
if (ret < 0 || static_cast<size_t>(ret) != 5 + kLengths[i]) {
fprintf(stderr, "BIO_printf failed: %d\n", ret);
return false;
}
const uint8_t *contents;
size_t len;
if (!BIO_mem_contents(bio.get(), &contents, &len)) {
fprintf(stderr, "BIO_mem_contents failed\n");
return false;
}
if (len != 5 + kLengths[i] ||
strncmp((const char *)contents, "test ", 5) != 0 ||
strncmp((const char *)contents + 5, string, kLengths[i]) != 0) {
fprintf(stderr, "Contents did not match: %.*s\n", (int)len, contents);
return false;
}
if (!BIO_reset(bio.get())) {
fprintf(stderr, "BIO_reset failed\n");
return false;
}
}
return true;
}
static bool ReadASN1(bool should_succeed, const uint8_t *data, size_t data_len,
size_t expected_len, size_t max_len) {
ScopedBIO bio(BIO_new_mem_buf(data, data_len));
uint8_t *out;
size_t out_len;
int ok = BIO_read_asn1(bio.get(), &out, &out_len, max_len);
if (!ok) {
out = nullptr;
}
ScopedOpenSSLBytes out_storage(out);
if (should_succeed != (ok == 1)) {
return false;
}
if (should_succeed &&
(out_len != expected_len || memcmp(data, out, expected_len) != 0)) {
return false;
}
return true;
}
static bool TestASN1() {
static const uint8_t kData1[] = {0x30, 2, 1, 2, 0, 0};
static const uint8_t kData2[] = {0x30, 3, 1, 2}; /* truncated */
static const uint8_t kData3[] = {0x30, 0x81, 1, 1}; /* should be short len */
static const uint8_t kData4[] = {0x30, 0x82, 0, 1, 1}; /* zero padded. */
if (!ReadASN1(true, kData1, sizeof(kData1), 4, 100) ||
!ReadASN1(false, kData2, sizeof(kData2), 0, 100) ||
!ReadASN1(false, kData3, sizeof(kData3), 0, 100) ||
!ReadASN1(false, kData4, sizeof(kData4), 0, 100)) {
return false;
}
static const size_t kLargePayloadLen = 8000;
static const uint8_t kLargePrefix[] = {0x30, 0x82, kLargePayloadLen >> 8,
kLargePayloadLen & 0xff};
ScopedOpenSSLBytes large(reinterpret_cast<uint8_t *>(
OPENSSL_malloc(sizeof(kLargePrefix) + kLargePayloadLen)));
if (!large) {
return false;
}
memset(large.get() + sizeof(kLargePrefix), 0, kLargePayloadLen);
memcpy(large.get(), kLargePrefix, sizeof(kLargePrefix));
if (!ReadASN1(true, large.get(), sizeof(kLargePrefix) + kLargePayloadLen,
sizeof(kLargePrefix) + kLargePayloadLen,
kLargePayloadLen * 2)) {
fprintf(stderr, "Large payload test failed.\n");
return false;
}
if (!ReadASN1(false, large.get(), sizeof(kLargePrefix) + kLargePayloadLen,
sizeof(kLargePrefix) + kLargePayloadLen,
kLargePayloadLen - 1)) {
fprintf(stderr, "max_len test failed.\n");
return false;
}
static const uint8_t kIndefPrefix[] = {0x30, 0x80};
memcpy(large.get(), kIndefPrefix, sizeof(kIndefPrefix));
if (!ReadASN1(true, large.get(), sizeof(kLargePrefix) + kLargePayloadLen,
sizeof(kLargePrefix) + kLargePayloadLen,
kLargePayloadLen*2)) {
fprintf(stderr, "indefinite length test failed.\n");
return false;
}
if (!ReadASN1(false, large.get(), sizeof(kLargePrefix) + kLargePayloadLen,
sizeof(kLargePrefix) + kLargePayloadLen,
kLargePayloadLen-1)) {
fprintf(stderr, "indefinite length, max_len test failed.\n");
return false;
}
return true;
}
int main(void) {
CRYPTO_library_init();
#if defined(OPENSSL_WINDOWS)
// Initialize Winsock.
WORD wsa_version = MAKEWORD(2, 2);
WSADATA wsa_data;
int wsa_err = WSAStartup(wsa_version, &wsa_data);
if (wsa_err != 0) {
fprintf(stderr, "WSAStartup failed: %d\n", wsa_err);
return 1;
}
if (wsa_data.wVersion != wsa_version) {
fprintf(stderr, "Didn't get expected version: %x\n", wsa_data.wVersion);
return 1;
}
#endif
if (!TestSocketConnect() ||
!TestPrintf() ||
!TestZeroCopyBioPairs() ||
!TestASN1()) {
return 1;
}
printf("PASS\n");
return 0;
}

496
external/boringssl/crypto/bio/buffer.c vendored Normal file
View File

@@ -0,0 +1,496 @@
/* 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 <openssl/bio.h>
#include <string.h>
#include <openssl/buf.h>
#include <openssl/err.h>
#include <openssl/mem.h>
#define DEFAULT_BUFFER_SIZE 4096
typedef struct bio_f_buffer_ctx_struct {
/* Buffers are setup like this:
*
* <---------------------- size ----------------------->
* +---------------------------------------------------+
* | consumed | remaining | free space |
* +---------------------------------------------------+
* <-- off --><------- len ------->
*/
int ibuf_size; /* how big is the input buffer */
int obuf_size; /* how big is the output buffer */
char *ibuf; /* the char array */
int ibuf_len; /* how many bytes are in it */
int ibuf_off; /* write/read offset */
char *obuf; /* the char array */
int obuf_len; /* how many bytes are in it */
int obuf_off; /* write/read offset */
} BIO_F_BUFFER_CTX;
static int buffer_new(BIO *bio) {
BIO_F_BUFFER_CTX *ctx;
ctx = OPENSSL_malloc(sizeof(BIO_F_BUFFER_CTX));
if (ctx == NULL) {
return 0;
}
memset(ctx, 0, sizeof(BIO_F_BUFFER_CTX));
ctx->ibuf = OPENSSL_malloc(DEFAULT_BUFFER_SIZE);
if (ctx->ibuf == NULL) {
goto err1;
}
ctx->obuf = OPENSSL_malloc(DEFAULT_BUFFER_SIZE);
if (ctx->obuf == NULL) {
goto err2;
}
ctx->ibuf_size = DEFAULT_BUFFER_SIZE;
ctx->obuf_size = DEFAULT_BUFFER_SIZE;
bio->init = 1;
bio->ptr = (char *)ctx;
return 1;
err2:
OPENSSL_free(ctx->ibuf);
err1:
OPENSSL_free(ctx);
return 0;
}
static int buffer_free(BIO *bio) {
BIO_F_BUFFER_CTX *ctx;
if (bio == NULL || bio->ptr == NULL) {
return 0;
}
ctx = (BIO_F_BUFFER_CTX *)bio->ptr;
OPENSSL_free(ctx->ibuf);
OPENSSL_free(ctx->obuf);
OPENSSL_free(bio->ptr);
bio->ptr = NULL;
bio->init = 0;
bio->flags = 0;
return 1;
}
static int buffer_read(BIO *bio, char *out, int outl) {
int i, num = 0;
BIO_F_BUFFER_CTX *ctx;
ctx = (BIO_F_BUFFER_CTX *)bio->ptr;
if (ctx == NULL || bio->next_bio == NULL) {
return 0;
}
num = 0;
BIO_clear_retry_flags(bio);
for (;;) {
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(bio->next_bio, out, outl);
if (i <= 0) {
BIO_copy_next_retry(bio);
if (i < 0) {
return (num > 0) ? num : i;
}
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(bio->next_bio, ctx->ibuf, ctx->ibuf_size);
if (i <= 0) {
BIO_copy_next_retry(bio);
if (i < 0) {
return (num > 0) ? num : i;
}
return num;
}
ctx->ibuf_off = 0;
ctx->ibuf_len = i;
}
}
static int buffer_write(BIO *b, const char *in, int inl) {
int i, num = 0;
BIO_F_BUFFER_CTX *ctx;
ctx = (BIO_F_BUFFER_CTX *)b->ptr;
if (ctx == NULL || b->next_bio == NULL) {
return 0;
}
BIO_clear_retry_flags(b);
for (;;) {
i = ctx->obuf_size - (ctx->obuf_off + ctx->obuf_len);
/* 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) {
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;
}
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;
}
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 */
}
}
static long buffer_ctrl(BIO *b, int cmd, long num, void *ptr) {
BIO_F_BUFFER_CTX *ctx;
long ret = 1;
char *p1, *p2;
int r, *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 = ctx->obuf_len;
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_SIZE:
ip = (int *)ptr;
if (*ip == 0) {
ibs = (int)num;
obs = ctx->obuf_size;
} else /* if (*ip == 1) */ {
ibs = ctx->ibuf_size;
obs = (int)num;
}
p1 = ctx->ibuf;
p2 = ctx->obuf;
if (ibs > DEFAULT_BUFFER_SIZE && ibs != ctx->ibuf_size) {
p1 = OPENSSL_malloc(ibs);
if (p1 == NULL) {
goto malloc_error;
}
}
if (obs > DEFAULT_BUFFER_SIZE && obs != ctx->obuf_size) {
p2 = OPENSSL_malloc(obs);
if (p2 == NULL) {
if (p1 != ctx->ibuf) {
OPENSSL_free(p1);
}
goto malloc_error;
}
}
if (ctx->ibuf != p1) {
OPENSSL_free(ctx->ibuf);
ctx->ibuf = p1;
ctx->ibuf_size = ibs;
}
ctx->ibuf_off = 0;
ctx->ibuf_len = 0;
if (ctx->obuf != p2) {
OPENSSL_free(ctx->obuf);
ctx->obuf = p2;
ctx->obuf_size = obs;
}
ctx->obuf_off = 0;
ctx->obuf_len = 0;
break;
case BIO_CTRL_FLUSH:
if (b->next_bio == NULL) {
return 0;
}
while (ctx->obuf_len > 0) {
BIO_clear_retry_flags(b);
r = BIO_write(b->next_bio, &(ctx->obuf[ctx->obuf_off]),
ctx->obuf_len);
BIO_copy_next_retry(b);
if (r <= 0) {
return r;
}
ctx->obuf_off += r;
ctx->obuf_len -= r;
}
ctx->obuf_len = 0;
ctx->obuf_off = 0;
ret = BIO_ctrl(b->next_bio, cmd, num, ptr);
break;
default:
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;
}
return ret;
malloc_error:
OPENSSL_PUT_ERROR(BIO, 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;
if (buf == NULL || size <= 0) {
return 0;
}
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;
}
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));
}
static const BIO_METHOD methods_buffer = {
BIO_TYPE_BUFFER, "buffer", buffer_write, buffer_read,
buffer_puts, buffer_gets, buffer_ctrl, buffer_new,
buffer_free, buffer_callback_ctrl,
};
const BIO_METHOD *BIO_f_buffer(void) { return &methods_buffer; }
int BIO_set_read_buffer_size(BIO *bio, int buffer_size) {
return BIO_int_ctrl(bio, BIO_C_SET_BUFF_SIZE, buffer_size, 0);
}
int BIO_set_write_buffer_size(BIO *bio, int buffer_size) {
return BIO_int_ctrl(bio, BIO_C_SET_BUFF_SIZE, buffer_size, 1);
}

553
external/boringssl/crypto/bio/connect.c vendored Normal file

File diff suppressed because it is too large Load Diff

277
external/boringssl/crypto/bio/fd.c vendored Normal file
View File

@@ -0,0 +1,277 @@
/* 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 <openssl/bio.h>
#include <errno.h>
#include <string.h>
#if !defined(OPENSSL_WINDOWS)
#include <unistd.h>
#else
#include <io.h>
OPENSSL_MSVC_PRAGMA(warning(push, 3))
#include <windows.h>
OPENSSL_MSVC_PRAGMA(warning(pop))
#endif
#include <openssl/buf.h>
#include <openssl/err.h>
#include <openssl/mem.h>
#include "internal.h"
static int bio_fd_non_fatal_error(int err) {
if (
#ifdef EWOULDBLOCK
err == EWOULDBLOCK ||
#endif
#ifdef WSAEWOULDBLOCK
err == WSAEWOULDBLOCK ||
#endif
#ifdef ENOTCONN
err == ENOTCONN ||
#endif
#ifdef EINTR
err == EINTR ||
#endif
#ifdef EAGAIN
err == EAGAIN ||
#endif
#ifdef EPROTO
err == EPROTO ||
#endif
#ifdef EINPROGRESS
err == EINPROGRESS ||
#endif
#ifdef EALREADY
err == EALREADY ||
#endif
0) {
return 1;
}
return 0;
}
#if defined(OPENSSL_WINDOWS)
#define BORINGSSL_ERRNO (int)GetLastError()
#define BORINGSSL_CLOSE _close
#define BORINGSSL_LSEEK _lseek
#define BORINGSSL_READ _read
#define BORINGSSL_WRITE _write
#else
#define BORINGSSL_ERRNO errno
#define BORINGSSL_CLOSE close
#define BORINGSSL_LSEEK lseek
#define BORINGSSL_READ read
#define BORINGSSL_WRITE write
#endif
int bio_fd_should_retry(int i) {
if (i == -1) {
return bio_fd_non_fatal_error(BORINGSSL_ERRNO);
}
return 0;
}
BIO *BIO_new_fd(int fd, int close_flag) {
BIO *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 *bio) {
/* num is used to store the file descriptor. */
bio->num = -1;
return 1;
}
static int fd_free(BIO *bio) {
if (bio == NULL) {
return 0;
}
if (bio->shutdown) {
if (bio->init) {
BORINGSSL_CLOSE(bio->num);
}
bio->init = 0;
}
return 1;
}
static int fd_read(BIO *b, char *out, int outl) {
int ret = 0;
ret = BORINGSSL_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 = BORINGSSL_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 = 0;
if (b->init) {
ret = (long)BORINGSSL_LSEEK(b->num, num, SEEK_SET);
}
break;
case BIO_C_FILE_TELL:
case BIO_CTRL_INFO:
ret = 0;
if (b->init) {
ret = (long)BORINGSSL_LSEEK(b->num, 0, SEEK_CUR);
}
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;
}
return 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:
ret = 1;
break;
default:
ret = 0;
break;
}
return ret;
}
static int fd_puts(BIO *bp, const char *str) {
return fd_write(bp, str, strlen(str));
}
static int fd_gets(BIO *bp, char *buf, int size) {
char *ptr = buf;
char *end = buf + size - 1;
if (size <= 0) {
return 0;
}
while (ptr < end && fd_read(bp, ptr, 1) > 0 && ptr[0] != '\n') {
ptr++;
}
ptr[0] = '\0';
return ptr - buf;
}
static const BIO_METHOD methods_fdp = {
BIO_TYPE_FD, "file descriptor", fd_write, fd_read, fd_puts,
fd_gets, fd_ctrl, fd_new, fd_free, NULL, };
const BIO_METHOD *BIO_s_fd(void) { return &methods_fdp; }
int BIO_set_fd(BIO *bio, int fd, int close_flag) {
return BIO_int_ctrl(bio, BIO_C_SET_FD, close_flag, fd);
}
int BIO_get_fd(BIO *bio, int *out_fd) {
return BIO_ctrl(bio, BIO_C_GET_FD, 0, (char *) out_fd);
}

313
external/boringssl/crypto/bio/file.c vendored Normal file
View File

@@ -0,0 +1,313 @@
/* 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.] */
#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 <openssl/bio.h>
#include <errno.h>
#include <stdio.h>
#include <string.h>
#include <openssl/buf.h>
#include <openssl/err.h>
#include <openssl/mem.h>
#define BIO_FP_READ 0x02
#define BIO_FP_WRITE 0x04
#define BIO_FP_APPEND 0x08
BIO *BIO_new_file(const char *filename, const char *mode) {
BIO *ret;
FILE *file;
file = fopen(filename, mode);
if (file == NULL) {
OPENSSL_PUT_SYSTEM_ERROR();
ERR_add_error_data(5, "fopen('", filename, "','", mode, "')");
if (errno == ENOENT) {
OPENSSL_PUT_ERROR(BIO, BIO_R_NO_SUCH_FILE);
} else {
OPENSSL_PUT_ERROR(BIO, BIO_R_SYS_LIB);
}
return NULL;
}
ret = BIO_new(BIO_s_file());
if (ret == 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 = BIO_new(BIO_s_file());
if (ret == NULL) {
return NULL;
}
BIO_set_fp(ret, stream, close_flag);
return ret;
}
static int file_new(BIO *bio) { return 1; }
static int file_free(BIO *bio) {
if (bio == NULL) {
return 0;
}
if (!bio->shutdown) {
return 1;
}
if (bio->init && bio->ptr != NULL) {
fclose(bio->ptr);
bio->ptr = NULL;
}
bio->init = 0;
return 1;
}
static int file_read(BIO *b, char *out, int outl) {
if (!b->init) {
return 0;
}
size_t ret = fread(out, 1, outl, (FILE *)b->ptr);
if (ret == 0 && ferror((FILE *)b->ptr)) {
OPENSSL_PUT_SYSTEM_ERROR();
OPENSSL_PUT_ERROR(BIO, ERR_R_SYS_LIB);
return -1;
}
/* fread reads at most |outl| bytes, so |ret| fits in an int. */
return (int)ret;
}
static int file_write(BIO *b, const char *in, int inl) {
int ret = 0;
if (!b->init) {
return 0;
}
ret = fwrite(in, inl, 1, (FILE *)b->ptr);
if (ret > 0) {
ret = inl;
}
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_CTRL_RESET:
num = 0;
case BIO_C_FILE_SEEK:
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) {
BUF_strlcpy(p, "a+", sizeof(p));
} else {
BUF_strlcpy(p, "a", sizeof(p));
}
} else if ((num & BIO_FP_READ) && (num & BIO_FP_WRITE)) {
BUF_strlcpy(p, "r+", sizeof(p));
} else if (num & BIO_FP_WRITE) {
BUF_strlcpy(p, "w", sizeof(p));
} else if (num & BIO_FP_READ) {
BUF_strlcpy(p, "r", sizeof(p));
} else {
OPENSSL_PUT_ERROR(BIO, BIO_R_BAD_FOPEN_MODE);
ret = 0;
break;
}
fp = fopen(ptr, p);
if (fp == NULL) {
OPENSSL_PUT_SYSTEM_ERROR();
ERR_add_error_data(5, "fopen('", ptr, "','", p, "')");
OPENSSL_PUT_ERROR(BIO, 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:
ret = 0 == fflush((FILE *)b->ptr);
break;
case BIO_CTRL_WPENDING:
case BIO_CTRL_PENDING:
default:
ret = 0;
break;
}
return ret;
}
static int file_gets(BIO *bp, char *buf, int size) {
int ret = 0;
if (size == 0) {
return 0;
}
if (!fgets(buf, size, (FILE *)bp->ptr)) {
buf[0] = 0;
goto err;
}
ret = strlen(buf);
err:
return ret;
}
static int file_puts(BIO *bp, const char *str) {
return file_write(bp, str, strlen(str));
}
static const BIO_METHOD methods_filep = {
BIO_TYPE_FILE, "FILE pointer", file_write, file_read, file_puts,
file_gets, file_ctrl, file_new, file_free, NULL, };
const BIO_METHOD *BIO_s_file(void) { return &methods_filep; }
int BIO_get_fp(BIO *bio, FILE **out_file) {
return BIO_ctrl(bio, BIO_C_GET_FILE_PTR, 0, (char*) out_file);
}
int BIO_set_fp(BIO *bio, FILE *file, int close_flag) {
return BIO_ctrl(bio, BIO_C_SET_FILE_PTR, close_flag, (char *) file);
}
int BIO_read_filename(BIO *bio, const char *filename) {
return BIO_ctrl(bio, BIO_C_SET_FILENAME, BIO_CLOSE | BIO_FP_READ,
(char *)filename);
}
int BIO_write_filename(BIO *bio, const char *filename) {
return BIO_ctrl(bio, BIO_C_SET_FILENAME, BIO_CLOSE | BIO_FP_WRITE,
(char *)filename);
}
int BIO_append_filename(BIO *bio, const char *filename) {
return BIO_ctrl(bio, BIO_C_SET_FILENAME, BIO_CLOSE | BIO_FP_APPEND,
(char *)filename);
}
int BIO_rw_filename(BIO *bio, const char *filename) {
return BIO_ctrl(bio, BIO_C_SET_FILENAME,
BIO_CLOSE | BIO_FP_READ | BIO_FP_WRITE, (char *)filename);
}

192
external/boringssl/crypto/bio/hexdump.c vendored Normal file
View File

@@ -0,0 +1,192 @@
/* 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 <openssl/bio.h>
#include <limits.h>
#include <string.h>
/* hexdump_ctx contains the state of a hexdump. */
struct hexdump_ctx {
BIO *bio;
char right_chars[18]; /* the contents of the right-hand side, ASCII dump. */
unsigned used; /* number of bytes in the current line. */
size_t n; /* number of bytes total. */
unsigned indent;
};
static void hexbyte(char *out, uint8_t b) {
static const char hextable[] = "0123456789abcdef";
out[0] = hextable[b>>4];
out[1] = hextable[b&0x0f];
}
static char to_char(uint8_t b) {
if (b < 32 || b > 126) {
return '.';
}
return b;
}
/* hexdump_write adds |len| bytes of |data| to the current hex dump described by
* |ctx|. */
static int hexdump_write(struct hexdump_ctx *ctx, const uint8_t *data,
size_t len) {
size_t i;
char buf[10];
unsigned l;
/* Output lines look like:
* 00000010 2e 2f 30 31 32 33 34 35 36 37 38 ... 3c 3d // |./0123456789:;<=|
* ^ offset ^ extra space ^ ASCII of line
*/
for (i = 0; i < len; i++) {
if (ctx->used == 0) {
/* The beginning of a line. */
BIO_indent(ctx->bio, ctx->indent, UINT_MAX);
hexbyte(&buf[0], ctx->n >> 24);
hexbyte(&buf[2], ctx->n >> 16);
hexbyte(&buf[4], ctx->n >> 8);
hexbyte(&buf[6], ctx->n);
buf[8] = buf[9] = ' ';
if (BIO_write(ctx->bio, buf, 10) < 0) {
return 0;
}
}
hexbyte(buf, data[i]);
buf[2] = ' ';
l = 3;
if (ctx->used == 7) {
/* There's an additional space after the 8th byte. */
buf[3] = ' ';
l = 4;
} else if (ctx->used == 15) {
/* At the end of the line there's an extra space and the bar for the
* right column. */
buf[3] = ' ';
buf[4] = '|';
l = 5;
}
if (BIO_write(ctx->bio, buf, l) < 0) {
return 0;
}
ctx->right_chars[ctx->used] = to_char(data[i]);
ctx->used++;
ctx->n++;
if (ctx->used == 16) {
ctx->right_chars[16] = '|';
ctx->right_chars[17] = '\n';
if (BIO_write(ctx->bio, ctx->right_chars, sizeof(ctx->right_chars)) < 0) {
return 0;
}
ctx->used = 0;
}
}
return 1;
}
/* finish flushes any buffered data in |ctx|. */
static int finish(struct hexdump_ctx *ctx) {
/* See the comments in |hexdump| for the details of this format. */
const unsigned n_bytes = ctx->used;
unsigned l;
char buf[5];
if (n_bytes == 0) {
return 1;
}
memset(buf, ' ', 4);
buf[4] = '|';
for (; ctx->used < 16; ctx->used++) {
l = 3;
if (ctx->used == 7) {
l = 4;
} else if (ctx->used == 15) {
l = 5;
}
if (BIO_write(ctx->bio, buf, l) < 0) {
return 0;
}
}
ctx->right_chars[n_bytes] = '|';
ctx->right_chars[n_bytes + 1] = '\n';
if (BIO_write(ctx->bio, ctx->right_chars, n_bytes + 2) < 0) {
return 0;
}
return 1;
}
int BIO_hexdump(BIO *bio, const uint8_t *data, size_t len, unsigned indent) {
struct hexdump_ctx ctx;
memset(&ctx, 0, sizeof(ctx));
ctx.bio = bio;
ctx.indent = indent;
if (!hexdump_write(&ctx, data, len) || !finish(&ctx)) {
return 0;
}
return 1;
}

111
external/boringssl/crypto/bio/internal.h vendored Normal file
View File

@@ -0,0 +1,111 @@
/* 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.] */
#ifndef OPENSSL_HEADER_BIO_INTERNAL_H
#define OPENSSL_HEADER_BIO_INTERNAL_H
#include <openssl/base.h>
#if !defined(OPENSSL_WINDOWS)
#if defined(OPENSSL_PNACL)
/* newlib uses u_short in socket.h without defining it. */
typedef unsigned short u_short;
#endif
#include <sys/types.h>
#include <sys/socket.h>
#else
OPENSSL_MSVC_PRAGMA(warning(push, 3))
#include <winsock2.h>
OPENSSL_MSVC_PRAGMA(warning(pop))
typedef int socklen_t;
#endif
#if defined(__cplusplus)
extern "C" {
#endif
/* BIO_ip_and_port_to_socket_and_addr creates a socket and fills in |*out_addr|
* and |*out_addr_length| with the correct values for connecting to |hostname|
* on |port_str|. It returns one on success or zero on error. */
int bio_ip_and_port_to_socket_and_addr(int *out_sock,
struct sockaddr_storage *out_addr,
socklen_t *out_addr_length,
const char *hostname,
const char *port_str);
/* BIO_socket_nbio sets whether |sock| is non-blocking. It returns one on
* success and zero otherwise. */
int bio_socket_nbio(int sock, int on);
/* BIO_clear_socket_error clears the last system socket error.
*
* TODO(fork): remove all callers of this. */
void bio_clear_socket_error(void);
/* BIO_sock_error returns the last socket error on |sock|. */
int bio_sock_error(int sock);
/* BIO_fd_should_retry returns non-zero if |return_value| indicates an error
* and |errno| indicates that it's non-fatal. */
int bio_fd_should_retry(int return_value);
#if defined(__cplusplus)
} /* extern C */
#endif
#endif /* OPENSSL_HEADER_BIO_INTERNAL_H */

803
external/boringssl/crypto/bio/pair.c vendored Normal file

File diff suppressed because it is too large Load Diff

119
external/boringssl/crypto/bio/printf.c vendored Normal file
View File

@@ -0,0 +1,119 @@
/* 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.] */
#if !defined(_POSIX_C_SOURCE)
#define _POSIX_C_SOURCE 201410L /* for snprintf, vprintf etc */
#endif
#include <openssl/bio.h>
#include <assert.h>
#include <stdarg.h>
#include <stdio.h>
#include <openssl/err.h>
#include <openssl/mem.h>
int BIO_printf(BIO *bio, const char *format, ...) {
va_list args;
char buf[256], *out, out_malloced = 0;
int out_len, ret;
va_start(args, format);
out_len = vsnprintf(buf, sizeof(buf), format, args);
va_end(args);
#if defined(OPENSSL_WINDOWS)
/* On Windows, vsnprintf returns -1 rather than the requested length on
* truncation */
if (out_len < 0) {
va_start(args, format);
out_len = _vscprintf(format, args);
va_end(args);
assert(out_len >= sizeof(buf));
}
#endif
if (out_len < 0) {
return -1;
}
if ((size_t) out_len >= sizeof(buf)) {
const int requested_len = out_len;
/* The output was truncated. Note that vsnprintf's return value
* does not include a trailing NUL, but the buffer must be sized
* for it. */
out = OPENSSL_malloc(requested_len + 1);
out_malloced = 1;
if (out == NULL) {
OPENSSL_PUT_ERROR(BIO, ERR_R_MALLOC_FAILURE);
return -1;
}
va_start(args, format);
out_len = vsnprintf(out, requested_len + 1, format, args);
va_end(args);
assert(out_len == requested_len);
} else {
out = buf;
}
ret = BIO_write(bio, out, out_len);
if (out_malloced) {
OPENSSL_free(out);
}
return ret;
}

203
external/boringssl/crypto/bio/socket.c vendored Normal file
View File

@@ -0,0 +1,203 @@
/* crypto/bio/bss_sock.c */
/* 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 <openssl/bio.h>
#include <fcntl.h>
#include <string.h>
#if !defined(OPENSSL_WINDOWS)
#include <unistd.h>
#else
OPENSSL_MSVC_PRAGMA(warning(push, 3))
#include <winsock2.h>
OPENSSL_MSVC_PRAGMA(warning(pop))
#pragma comment(lib, "Ws2_32.lib")
#endif
#include "internal.h"
#if !defined(OPENSSL_WINDOWS)
static int closesocket(int sock) {
return close(sock);
}
#endif
static int sock_new(BIO *bio) {
bio->init = 0;
bio->num = 0;
bio->ptr = NULL;
bio->flags = 0;
return 1;
}
static int sock_free(BIO *bio) {
if (bio == NULL) {
return 0;
}
if (bio->shutdown) {
if (bio->init) {
closesocket(bio->num);
}
bio->init = 0;
bio->flags = 0;
}
return 1;
}
static int sock_read(BIO *b, char *out, int outl) {
int ret = 0;
if (out == NULL) {
return 0;
}
bio_clear_socket_error();
#if defined(OPENSSL_WINDOWS)
ret = recv(b->num, out, outl, 0);
#else
ret = read(b->num, out, outl);
#endif
BIO_clear_retry_flags(b);
if (ret <= 0) {
if (bio_fd_should_retry(ret)) {
BIO_set_retry_read(b);
}
}
return ret;
}
static int sock_write(BIO *b, const char *in, int inl) {
int ret;
bio_clear_socket_error();
#if defined(OPENSSL_WINDOWS)
ret = send(b->num, in, inl, 0);
#else
ret = write(b->num, in, inl);
#endif
BIO_clear_retry_flags(b);
if (ret <= 0) {
if (bio_fd_should_retry(ret)) {
BIO_set_retry_write(b);
}
}
return ret;
}
static int sock_puts(BIO *bp, const char *str) {
return sock_write(bp, str, strlen(str));
}
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_FLUSH:
ret = 1;
break;
default:
ret = 0;
break;
}
return ret;
}
static const BIO_METHOD methods_sockp = {
BIO_TYPE_SOCKET, "socket", sock_write, sock_read, sock_puts,
NULL /* gets, */, sock_ctrl, sock_new, sock_free, NULL,
};
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;
}

View File

@@ -0,0 +1,113 @@
/* Copyright (c) 2014, Google Inc.
*
* Permission to use, copy, modify, and/or 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. */
#undef _POSIX_C_SOURCE
#define _POSIX_C_SOURCE 200112L
#include <openssl/bio.h>
#include <openssl/err.h>
#include <fcntl.h>
#include <string.h>
#include <sys/types.h>
#if !defined(OPENSSL_WINDOWS)
#include <netdb.h>
#include <unistd.h>
#else
OPENSSL_MSVC_PRAGMA(warning(push, 3))
#include <winsock2.h>
#include <ws2tcpip.h>
OPENSSL_MSVC_PRAGMA(warning(pop))
#endif
#include "internal.h"
int bio_ip_and_port_to_socket_and_addr(int *out_sock,
struct sockaddr_storage *out_addr,
socklen_t *out_addr_length,
const char *hostname,
const char *port_str) {
struct addrinfo hint, *result, *cur;
int ret;
*out_sock = -1;
memset(&hint, 0, sizeof(hint));
hint.ai_family = AF_UNSPEC;
hint.ai_socktype = SOCK_STREAM;
ret = getaddrinfo(hostname, port_str, &hint, &result);
if (ret != 0) {
OPENSSL_PUT_ERROR(SYS, 0);
ERR_add_error_data(1, gai_strerror(ret));
return 0;
}
ret = 0;
for (cur = result; cur; cur = cur->ai_next) {
if ((size_t) cur->ai_addrlen > sizeof(struct sockaddr_storage)) {
continue;
}
memset(out_addr, 0, sizeof(struct sockaddr_storage));
memcpy(out_addr, cur->ai_addr, cur->ai_addrlen);
*out_addr_length = cur->ai_addrlen;
*out_sock = socket(cur->ai_family, cur->ai_socktype, cur->ai_protocol);
if (*out_sock < 0) {
OPENSSL_PUT_SYSTEM_ERROR();
goto out;
}
ret = 1;
break;
}
out:
freeaddrinfo(result);
return ret;
}
int bio_socket_nbio(int sock, int on) {
#if defined(OPENSSL_WINDOWS)
u_long arg = on;
return 0 == ioctlsocket(sock, FIONBIO, &arg);
#else
int flags = fcntl(sock, F_GETFL, 0);
if (flags < 0) {
return 0;
}
if (!on) {
flags &= ~O_NONBLOCK;
} else {
flags |= O_NONBLOCK;
}
return fcntl(sock, F_SETFL, flags) == 0;
#endif
}
void bio_clear_socket_error(void) {}
int bio_sock_error(int sock) {
int error;
socklen_t error_size = sizeof(error);
if (getsockopt(sock, SOL_SOCKET, SO_ERROR, (char *)&error, &error_size) < 0) {
return 1;
}
return error;
}