Skip to content

Commit

Permalink
Use BoringSSL for TLS. (apple#59)
Browse files Browse the repository at this point in the history
Motivation:

Requiring the system's SSL library was a constant source of problems. 

Modifications:

This is the patch that transitions swift-nio-ssl to use BoringSSL, as discussed in [the Swift forums](https://forums.swift.org/t/rfc-moving-swiftnio-ssl-to-boringssl/18280).

Result:

Easier SSL support
  • Loading branch information
Lukasa authored and weissi committed Feb 25, 2019
1 parent 73c8380 commit 141ff46
Show file tree
Hide file tree
Showing 588 changed files with 417,604 additions and 950 deletions.
19 changes: 19 additions & 0 deletions NOTICE.txt
Original file line number Diff line number Diff line change
Expand Up @@ -41,3 +41,22 @@ This product contains a derivation of the Tony Stone's 'process_test_files.rb'.
* https://www.apache.org/licenses/LICENSE-2.0
* HOMEPAGE:
* https://codegists.com/snippet/ruby/generate_xctest_linux_runnerrb_tonystone_ruby

---

This product contains code derived from grpc-swift.

* LICENSE (Apache License 2.0):
* https://github.com/grpc/grpc-swift/blob/0.7.0/LICENSE
* HOMEPAGE:
* https://github.com/grpc/grpc-swift

---

This product contains code from boringssl.

* LICENSE (Combination ISC and OpenSSL license)
* https://boringssl.googlesource.com/boringssl/+/refs/heads/master/LICENSE
* HOMEPAGE:
* https://boringssl.googlesource.com/boringssl/

14 changes: 8 additions & 6 deletions Package.swift
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// swift-tools-version:4.0
// swift-tools-version:5.0
//===----------------------------------------------------------------------===//
//
// This source file is part of the SwiftNIO open source project
Expand All @@ -20,16 +20,18 @@ let package = Package(
products: [
.library(name: "NIOOpenSSL", targets: ["NIOOpenSSL"]),
.executable(name: "NIOTLSServer", targets: ["NIOTLSServer"]),
.library(name: "CNIOBoringSSL", type: .static, targets: ["CNIOBoringSSL"]),
],
dependencies: [
.package(url: "https://github.com/apple/swift-nio.git", from: "1.12.0"),
.package(url: "https://github.com/apple/swift-nio-ssl-support.git", from: "1.0.0"),
.package(url: "https://github.com/apple/swift-nio.git", .branch("master")),
],
targets: [
.target(name: "CNIOOpenSSL"),
.target(name: "CNIOBoringSSL"),
.target(name: "CNIOBoringSSLShims", dependencies: ["CNIOBoringSSL"]),
.target(name: "NIOOpenSSL",
dependencies: ["NIO", "NIOConcurrencyHelpers", "CNIOOpenSSL", "NIOTLS"]),
dependencies: ["NIO", "NIOConcurrencyHelpers", "CNIOBoringSSL", "CNIOBoringSSLShims", "NIOTLS", "_NIO1APIShims"]),
.target(name: "NIOTLSServer", dependencies: ["NIO", "NIOOpenSSL", "NIOConcurrencyHelpers"]),
.testTarget(name: "NIOOpenSSLTests", dependencies: ["NIOTLS", "NIOOpenSSL"]),
]
],
cxxLanguageStandard: .cxx11
)
271 changes: 271 additions & 0 deletions Sources/CNIOBoringSSL/crypto/asn1/a_bitstr.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,271 @@
/* Copyright (C) 1995-1998 Eric Young ([email protected])
* All rights reserved.
*
* This package is an SSL implementation written
* by Eric Young ([email protected]).
* 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 ([email protected]).
*
* 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 ([email protected])"
* 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 ([email protected])"
*
* 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/asn1.h"

#include "limits.h"
#include "string.h"

#include "openssl/err.h"
#include "openssl/mem.h"

#include "../internal.h"


int ASN1_BIT_STRING_set(ASN1_BIT_STRING *x, unsigned char *d, int len)
{
return M_ASN1_BIT_STRING_set(x, d, len);
}

int i2c_ASN1_BIT_STRING(ASN1_BIT_STRING *a, unsigned char **pp)
{
int ret, j, bits, len;
unsigned char *p, *d;

if (a == NULL)
return (0);

len = a->length;

if (len > 0) {
if (a->flags & ASN1_STRING_FLAG_BITS_LEFT) {
bits = (int)a->flags & 0x07;
} else {
for (; len > 0; len--) {
if (a->data[len - 1])
break;
}
j = a->data[len - 1];
if (j & 0x01)
bits = 0;
else if (j & 0x02)
bits = 1;
else if (j & 0x04)
bits = 2;
else if (j & 0x08)
bits = 3;
else if (j & 0x10)
bits = 4;
else if (j & 0x20)
bits = 5;
else if (j & 0x40)
bits = 6;
else if (j & 0x80)
bits = 7;
else
bits = 0; /* should not happen */
}
} else
bits = 0;

ret = 1 + len;
if (pp == NULL)
return (ret);

p = *pp;

*(p++) = (unsigned char)bits;
d = a->data;
OPENSSL_memcpy(p, d, len);
p += len;
if (len > 0)
p[-1] &= (0xff << bits);
*pp = p;
return (ret);
}

ASN1_BIT_STRING *c2i_ASN1_BIT_STRING(ASN1_BIT_STRING **a,
const unsigned char **pp, long len)
{
ASN1_BIT_STRING *ret = NULL;
const unsigned char *p;
unsigned char *s;
int padding;

if (len < 1) {
OPENSSL_PUT_ERROR(ASN1, ASN1_R_STRING_TOO_SHORT);
goto err;
}

if (len > INT_MAX) {
OPENSSL_PUT_ERROR(ASN1, ASN1_R_STRING_TOO_LONG);
goto err;
}

if ((a == NULL) || ((*a) == NULL)) {
if ((ret = M_ASN1_BIT_STRING_new()) == NULL)
return (NULL);
} else
ret = (*a);

p = *pp;
padding = *(p++);
if (padding > 7) {
OPENSSL_PUT_ERROR(ASN1, ASN1_R_INVALID_BIT_STRING_BITS_LEFT);
goto err;
}

/*
* We do this to preserve the settings. If we modify the settings, via
* the _set_bit function, we will recalculate on output
*/
ret->flags &= ~(ASN1_STRING_FLAG_BITS_LEFT | 0x07); /* clear */
ret->flags |= (ASN1_STRING_FLAG_BITS_LEFT | padding); /* set */

if (len-- > 1) { /* using one because of the bits left byte */
s = (unsigned char *)OPENSSL_malloc((int)len);
if (s == NULL) {
OPENSSL_PUT_ERROR(ASN1, ERR_R_MALLOC_FAILURE);
goto err;
}
OPENSSL_memcpy(s, p, (int)len);
s[len - 1] &= (0xff << padding);
p += len;
} else
s = NULL;

ret->length = (int)len;
if (ret->data != NULL)
OPENSSL_free(ret->data);
ret->data = s;
ret->type = V_ASN1_BIT_STRING;
if (a != NULL)
(*a) = ret;
*pp = p;
return (ret);
err:
if ((ret != NULL) && ((a == NULL) || (*a != ret)))
M_ASN1_BIT_STRING_free(ret);
return (NULL);
}

/*
* These next 2 functions from Goetz Babin-Ebell <[email protected]>
*/
int ASN1_BIT_STRING_set_bit(ASN1_BIT_STRING *a, int n, int value)
{
int w, v, iv;
unsigned char *c;

w = n / 8;
v = 1 << (7 - (n & 0x07));
iv = ~v;
if (!value)
v = 0;

if (a == NULL)
return 0;

a->flags &= ~(ASN1_STRING_FLAG_BITS_LEFT | 0x07); /* clear, set on write */

if ((a->length < (w + 1)) || (a->data == NULL)) {
if (!value)
return (1); /* Don't need to set */
if (a->data == NULL)
c = (unsigned char *)OPENSSL_malloc(w + 1);
else
c = (unsigned char *)OPENSSL_realloc(a->data, w + 1);
if (c == NULL) {
OPENSSL_PUT_ERROR(ASN1, ERR_R_MALLOC_FAILURE);
return 0;
}
if (w + 1 - a->length > 0)
OPENSSL_memset(c + a->length, 0, w + 1 - a->length);
a->data = c;
a->length = w + 1;
}
a->data[w] = ((a->data[w]) & iv) | v;
while ((a->length > 0) && (a->data[a->length - 1] == 0))
a->length--;
return (1);
}

int ASN1_BIT_STRING_get_bit(ASN1_BIT_STRING *a, int n)
{
int w, v;

w = n / 8;
v = 1 << (7 - (n & 0x07));
if ((a == NULL) || (a->length < (w + 1)) || (a->data == NULL))
return (0);
return ((a->data[w] & v) != 0);
}

/*
* Checks if the given bit string contains only bits specified by
* the flags vector. Returns 0 if there is at least one bit set in 'a'
* which is not specified in 'flags', 1 otherwise.
* 'len' is the length of 'flags'.
*/
int ASN1_BIT_STRING_check(ASN1_BIT_STRING *a,
unsigned char *flags, int flags_len)
{
int i, ok;
/* Check if there is one bit set at all. */
if (!a || !a->data)
return 1;

/*
* Check each byte of the internal representation of the bit string.
*/
ok = 1;
for (i = 0; i < a->length && ok; ++i) {
unsigned char mask = i < flags_len ? ~flags[i] : 0xff;
/* We are done if there is an unneeded bit set. */
ok = (a->data[i] & mask) == 0;
}
return ok;
}
Loading

0 comments on commit 141ff46

Please sign in to comment.