1
0
mirror of https://github.com/dart-lang/sdk synced 2024-07-08 12:06:26 +00:00

Breaking Change: merge BoringSSL branch into master

This replaces the NSS secure networking library from Mozilla
with the BoringSSL library from Google. This library, based
on OpenSSL, reads certificates from files in PEM format, rather
than storing certificates and keys in a SQLite database, the
way NSS does. There will be a blog post, changelog entries,
and other documentation of the breaking changes.

Review URL: https://codereview.chromium.org//1319703002 .
This commit is contained in:
William Hesse 2015-08-26 14:42:12 +02:00
parent 9a3b5614de
commit 13bf8ff9f8
192 changed files with 165741 additions and 4407 deletions

10
DEPS
View File

@ -42,6 +42,7 @@ vars = {
"args_tag": "@0.13.0",
"async_tag": "@1.2.0",
"barback_tag" : "@0.15.2+6",
"boringssl_rev" : "@daeafc22c66ad48f6b32fc8d3362eb9ba31b774e",
"charcode_tag": "@1.1.0",
"chrome_rev" : "@19997",
"clang_rev" : "@28450",
@ -89,6 +90,7 @@ vars = {
"pub_cache_tag": "@v0.1.0",
"pub_semver_tag": "@1.2.1",
"quiver_tag": "@0.21.4",
"root_certificates_rev": "@c3a41df63afacec62fcb8135196177e35fe72f71",
"scheduled_test_tag": "@0.12.1+2",
"shelf_rev": "@1e87b79b21ac5e6fa2f93576d6c06eaa65285ef4",
"smoke_rev" : "@f3361191cc2a85ebc1e4d4c33aec672d7915aba9",
@ -143,6 +145,14 @@ deps = {
Var("chromium_git") + "/chromium/src/net/third_party/nss.git" +
Var("net_nss_rev"),
Var("dart_root") + "/third_party/boringssl/src":
"https://boringssl.googlesource.com/boringssl.git" +
Var("boringssl_rev"),
Var("dart_root") + "/third_party/root_certificates":
"https://github.com/dart-lang/root_certificates.git" +
Var("root_certificates_rev"),
Var("dart_root") + "/third_party/jinja2":
Var("chromium_git") + "/chromium/src/third_party/jinja2.git" +
Var("jinja2_rev"),

View File

@ -222,11 +222,6 @@
['exclude', '_test\\.(cc|h)$'],
],
'conditions': [
['dart_io_support==1 and dart_io_secure_socket==1', {
'dependencies': [
'bin/net/ssl.gyp:libssl_dart',
],
}],
['dart_io_secure_socket==0', {
'defines': [
'DART_IO_SECURE_SOCKET_DISABLED'
@ -292,16 +287,16 @@
'io_natives.cc',
],
'conditions': [
['dart_io_support==1 and dart_io_secure_socket==1', {
'dependencies': [
'bin/net/ssl.gyp:libssl_dart',
],
}],
['dart_io_support==1 and dart_io_secure_socket==0', {
['dart_io_support==1', {
'dependencies': [
'bin/net/zlib.gyp:zlib_dart',
],
}],
['dart_io_support==1 and dart_io_secure_socket==1', {
'dependencies': [
'../third_party/boringssl/boringssl_dart.gyp:boringssl',
],
}],
['dart_io_secure_socket==0', {
'defines': [
'DART_IO_SECURE_SOCKET_DISABLED'
@ -333,19 +328,6 @@
},
}],
],
'configurations': {
'Dart_Android_Base': {
'target_conditions': [
['_toolset=="target"', {
'defines': [
# Needed for sources outside of nss that include pr and ssl
# header files.
'MDCPUCFG="md/_linux.cfg"',
],
}],
],
},
},
},
{
'target_name': 'libdart_nosnapshot',

View File

@ -26,9 +26,9 @@
'filter_unsupported.cc',
'io_service.cc',
'io_service.h',
'io_service_no_ssl.cc',
'io_service_no_ssl.h',
'io_service_unsupported.cc',
'net/nss_memio.cc',
'net/nss_memio.h',
'platform.cc',
'platform.h',
'platform_android.cc',
@ -41,6 +41,7 @@
'process_linux.cc',
'process_macos.cc',
'process_win.cc',
'../../third_party/root_certificates/root_certificates.cc',
'secure_socket.cc',
'secure_socket.h',
'secure_socket_unsupported.cc',
@ -62,12 +63,15 @@
'conditions': [
['dart_io_secure_socket==1', {
'sources!' : [
'io_service_no_ssl.cc',
'io_service_no_ssl.h',
'secure_socket_unsupported.cc',
],
}, { # else dart_io_secure_socket == 0
'sources!' : [
'net/nss_memio.cc',
'net/nss_memio.h',
'../../third_party/root_certificates/root_certificates.cc',
'io_service.cc',
'io_service.h',
'secure_socket.cc',
'secure_socket.h',
],
@ -83,8 +87,9 @@
'filter.h',
'io_service.cc',
'io_service.h',
'net/nss_memio.cc',
'net/nss_memio.h',
'io_service_no_ssl.cc',
'io_service_no_ssl.h',
'../../third_party/root_certificates/root_certificates.cc',
'secure_socket.cc',
'secure_socket.h',
],

View File

@ -96,17 +96,23 @@ namespace bin {
V(Process_Pid, 1) \
V(Process_SetSignalHandler, 1) \
V(Process_ClearSignalHandler, 1) \
V(SecureSocket_Connect, 10) \
V(SecureSocket_Connect, 8) \
V(SecureSocket_Destroy, 1) \
V(SecureSocket_FilterPointer, 1) \
V(SecureSocket_GetSelectedProtocol, 1) \
V(SecureSocket_Handshake, 1) \
V(SecureSocket_Init, 1) \
V(SecureSocket_InitializeLibrary, 3) \
V(SecureSocket_PeerCertificate, 1) \
V(SecureSocket_RegisterBadCertificateCallback, 2) \
V(SecureSocket_RegisterHandshakeCompleteCallback, 2) \
V(SecureSocket_Renegotiate, 4) \
V(SecurityContext_Allocate, 1) \
V(SecurityContext_UsePrivateKey, 3) \
V(SecurityContext_SetAlpnProtocols, 3) \
V(SecurityContext_SetClientAuthorities, 2) \
V(SecurityContext_SetTrustedCertificates, 3) \
V(SecurityContext_TrustBuiltinRoots, 1) \
V(SecurityContext_UseCertificateChain, 2) \
V(ServerSocket_Accept, 2) \
V(ServerSocket_CreateBindListen, 6) \
V(Socket_CreateConnect, 3) \
@ -136,8 +142,11 @@ namespace bin {
V(Stdin_SetLineMode, 1) \
V(Stdout_GetTerminalSize, 1) \
V(StringToSystemEncoding, 1) \
V(SystemEncodingToString, 1)
V(SystemEncodingToString, 1) \
V(X509_Subject, 1) \
V(X509_Issuer, 1) \
V(X509_StartValidity, 1) \
V(X509_EndValidity, 1)
IO_NATIVE_LIST(DECLARE_FUNCTION);

View File

@ -0,0 +1,78 @@
// Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
#include "bin/dartutils.h"
#include "bin/directory.h"
#include "bin/file.h"
#include "bin/io_buffer.h"
#include "bin/io_service_no_ssl.h"
#include "bin/socket.h"
#include "bin/utils.h"
#include "platform/globals.h"
#include "platform/utils.h"
#include "include/dart_api.h"
namespace dart {
namespace bin {
#define CASE_REQUEST(type, method, id) \
case IOService::k##type##method##Request: \
response = type::method##Request(data); \
break;
void IOServiceCallback(Dart_Port dest_port_id,
Dart_CObject* message) {
Dart_Port reply_port_id = ILLEGAL_PORT;
CObject* response = CObject::IllegalArgumentError();
CObjectArray request(message);
if (message->type == Dart_CObject_kArray &&
request.Length() == 4 &&
request[0]->IsInt32() &&
request[1]->IsSendPort() &&
request[2]->IsInt32() &&
request[3]->IsArray()) {
CObjectInt32 message_id(request[0]);
CObjectSendPort reply_port(request[1]);
CObjectInt32 request_id(request[2]);
CObjectArray data(request[3]);
reply_port_id = reply_port.Value();
switch (request_id.Value()) {
IO_SERVICE_REQUEST_LIST(CASE_REQUEST);
default:
UNREACHABLE();
}
}
CObjectArray result(CObject::NewArray(2));
result.SetAt(0, request[0]);
result.SetAt(1, response);
ASSERT(reply_port_id != ILLEGAL_PORT);
Dart_PostCObject(reply_port_id, result.AsApiCObject());
}
Dart_Port IOService::GetServicePort() {
Dart_Port result = Dart_NewNativePort("IOService",
IOServiceCallback,
true);
return result;
}
void FUNCTION_NAME(IOService_NewServicePort)(Dart_NativeArguments args) {
Dart_SetReturnValue(args, Dart_Null());
Dart_Port service_port = IOService::GetServicePort();
if (service_port != ILLEGAL_PORT) {
// Return a send port for the service port.
Dart_Handle send_port = Dart_NewSendPort(service_port);
Dart_SetReturnValue(args, send_port);
}
}
} // namespace bin
} // namespace dart

View File

@ -0,0 +1,74 @@
// Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
#ifndef BIN_IO_SERVICE_NO_SSL_H_
#define BIN_IO_SERVICE_NO_SSL_H_
#include "bin/builtin.h"
#include "bin/utils.h"
namespace dart {
namespace bin {
// This list must be kept in sync with the list in sdk/lib/io/io_service.dart
// In this modified version, though, the request 39 for SSLFilter::ProcessFilter
// is removed, for use in contexts in which secure sockets are not enabled.
#define IO_SERVICE_REQUEST_LIST(V) \
V(File, Exists, 0) \
V(File, Create, 1) \
V(File, Delete, 2) \
V(File, Rename, 3) \
V(File, Copy, 4) \
V(File, Open, 5) \
V(File, ResolveSymbolicLinks, 6) \
V(File, Close, 7) \
V(File, Position, 8) \
V(File, SetPosition, 9) \
V(File, Truncate, 10) \
V(File, Length, 11) \
V(File, LengthFromPath, 12) \
V(File, LastModified, 13) \
V(File, Flush, 14) \
V(File, ReadByte, 15) \
V(File, WriteByte, 16) \
V(File, Read, 17) \
V(File, ReadInto, 18) \
V(File, WriteFrom, 19) \
V(File, CreateLink, 20) \
V(File, DeleteLink, 21) \
V(File, RenameLink, 22) \
V(File, LinkTarget, 23) \
V(File, Type, 24) \
V(File, Identical, 25) \
V(File, Stat, 26) \
V(File, Lock, 27) \
V(Socket, Lookup, 28) \
V(Socket, ListInterfaces, 29) \
V(Socket, ReverseLookup, 30) \
V(Directory, Create, 31) \
V(Directory, Delete, 32) \
V(Directory, Exists, 33) \
V(Directory, CreateTemp, 34) \
V(Directory, ListStart, 35) \
V(Directory, ListNext, 36) \
V(Directory, ListStop, 37) \
V(Directory, Rename, 38)
#define DECLARE_REQUEST(type, method, id) \
k##type##method##Request = id,
class IOService {
public:
enum {
IO_SERVICE_REQUEST_LIST(DECLARE_REQUEST)
};
static Dart_Port GetServicePort();
};
} // namespace bin
} // namespace dart
#endif // BIN_IO_SERVICE_NO_SSL_H_

View File

@ -1,34 +0,0 @@
# Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file
# for details. All rights reserved. Use of this source code is governed by a
# BSD-style license that can be found in the LICENSE file.
The standalone Dart executable uses the NSS library from Mozilla to
support secure networking connections (SSL and TLS). It uses a copy
of the library from the Chromium repository, that includes patches
added by Chromium. We pin this to a fixed revision, using the
nss_revision variable in all the DEPS files in the deps directory of
the Dart repository.
This revision should be updated when new security fixes are added to
NSS, or every few months. The .gyp files in this directory are copies
of the .gyp files in the Chromium copy of NSS, with changes made to
account for the configurations and directory structure of the Dart
repository. Differences between the Chromium versions and the Dart
versions should be annotated with "# Added by Dart'.
All the files should have a comment saying where the original file is
in the Chromium repository. To update these files, look at the diff
between the two revisions in Chromium, and apply the changes manually,
with any needed modifications, to the Dart copies. Our aim is to keep
the difference between the Chromium and Dart copies as small as
possible.
The nss_memio.cc and nss_memio.h files are also taken from Chromium,
and should be updated at the same time. The os_Linux.s file is new,
and should not need changing.
The file nss.gyp includes support for disabling compilation of NSS
using the variable dart_io_support, when building configurations that
don't use it. NSS compilation is disabled when building Dartium,
because Chromium includes its own copy, and the build process would
get confused.

File diff suppressed because it is too large Load Diff

View File

@ -1,538 +0,0 @@
// Copyright (c) 2008 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// Written in NSPR style to also be suitable for adding to the NSS demo suite
// Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
// This file is a modified copy of Chromium's src/net/base/nss_memio.c.
// char* has been changed to uint8_t* everywhere, and C++ casts are used.
// Revision 291806 (this should agree with "nss_rev" in DEPS).
/* memio is a simple NSPR I/O layer that lets you decouple NSS from
* the real network. It's rather like openssl's memory bio,
* and is useful when your app absolutely, positively doesn't
* want to let NSS do its own networking.
*/
#include "bin/net/nss_memio.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "prerror.h"
#include "prinit.h"
#include "prlog.h"
/*--------------- private memio types -----------------------*/
/*----------------------------------------------------------------------
Simple private circular buffer class. Size cannot be changed once allocated.
----------------------------------------------------------------------*/
struct memio_buffer {
int head; /* where to take next byte out of buf */
int tail; /* where to put next byte into buf */
int bufsize; /* number of bytes allocated to buf */
/* TODO(port): error handling is pessimistic right now.
* Once an error is set, the socket is considered broken
* (PR_WOULD_BLOCK_ERROR not included).
*/
PRErrorCode last_err;
uint8_t* buf;
};
/* The 'secret' field of a PRFileDesc created by memio_CreateIOLayer points
* to one of these.
* In the public header, we use struct memio_Private as a typesafe alias
* for this. This causes a few ugly typecasts in the private file, but
* seems safer.
*/
struct PRFilePrivate {
/* read requests are satisfied from this buffer */
struct memio_buffer readbuf;
/* write requests are satisfied from this buffer */
struct memio_buffer writebuf;
/* SSL needs to know socket peer's name */
PRNetAddr peername;
/* if set, empty I/O returns EOF instead of EWOULDBLOCK */
int eof;
/* if set, the number of bytes requested from readbuf that were not
* fulfilled (due to readbuf being empty) */
int read_requested;
};
/*--------------- private memio_buffer functions ---------------------*/
/* Forward declarations. */
/* Allocate a memio_buffer of given size. */
static void memio_buffer_new(struct memio_buffer *mb, int size);
/* Deallocate a memio_buffer allocated by memio_buffer_new. */
static void memio_buffer_destroy(struct memio_buffer *mb);
/* How many bytes can be read out of the buffer without wrapping */
static int memio_buffer_used_contiguous(const struct memio_buffer *mb);
/* How many bytes exist after the wrap? */
static int memio_buffer_wrapped_bytes(const struct memio_buffer *mb);
/* How many bytes can be written into the buffer without wrapping */
static int memio_buffer_unused_contiguous(const struct memio_buffer *mb);
/* Write n bytes into the buffer. Returns number of bytes written. */
static int memio_buffer_put(struct memio_buffer *mb, const uint8_t* buf, int n);
/* Read n bytes from the buffer. Returns number of bytes read. */
static int memio_buffer_get(struct memio_buffer *mb, uint8_t* buf, int n);
/* Allocate a memio_buffer of given size. */
static void memio_buffer_new(struct memio_buffer *mb, int size) {
mb->head = 0;
mb->tail = 0;
mb->bufsize = size;
mb->buf = static_cast<uint8_t*>(malloc(size));
}
/* Deallocate a memio_buffer allocated by memio_buffer_new. */
static void memio_buffer_destroy(struct memio_buffer *mb) {
free(mb->buf);
mb->buf = NULL;
mb->bufsize = 0;
mb->head = 0;
mb->tail = 0;
}
/* How many bytes can be read out of the buffer without wrapping */
static int memio_buffer_used_contiguous(const struct memio_buffer *mb) {
return (((mb->tail >= mb->head) ? mb->tail : mb->bufsize) - mb->head);
}
/* How many bytes exist after the wrap? */
static int memio_buffer_wrapped_bytes(const struct memio_buffer *mb) {
return (mb->tail >= mb->head) ? 0 : mb->tail;
}
/* How many bytes can be written into the buffer without wrapping */
static int memio_buffer_unused_contiguous(const struct memio_buffer *mb) {
if (mb->head > mb->tail) return mb->head - mb->tail - 1;
return mb->bufsize - mb->tail - (mb->head == 0);
}
/* Write n bytes into the buffer. Returns number of bytes written. */
static int memio_buffer_put(struct memio_buffer *mb,
const uint8_t* buf,
int n) {
int len;
int transferred = 0;
/* Handle part before wrap */
len = PR_MIN(n, memio_buffer_unused_contiguous(mb));
if (len > 0) {
/* Buffer not full */
memmove(&mb->buf[mb->tail], buf, len);
mb->tail += len;
if (mb->tail == mb->bufsize)
mb->tail = 0;
n -= len;
buf += len;
transferred += len;
/* Handle part after wrap */
len = PR_MIN(n, memio_buffer_unused_contiguous(mb));
if (len > 0) {
/* Output buffer still not full, input buffer still not empty */
memmove(&mb->buf[mb->tail], buf, len);
mb->tail += len;
if (mb->tail == mb->bufsize)
mb->tail = 0;
transferred += len;
}
}
return transferred;
}
/* Read n bytes from the buffer. Returns number of bytes read. */
static int memio_buffer_get(struct memio_buffer *mb, uint8_t* buf, int n) {
int len;
int transferred = 0;
/* Handle part before wrap */
len = PR_MIN(n, memio_buffer_used_contiguous(mb));
if (len) {
memmove(buf, &mb->buf[mb->head], len);
mb->head += len;
if (mb->head == mb->bufsize)
mb->head = 0;
n -= len;
buf += len;
transferred += len;
/* Handle part after wrap */
len = PR_MIN(n, memio_buffer_used_contiguous(mb));
if (len) {
memmove(buf, &mb->buf[mb->head], len);
mb->head += len;
if (mb->head == mb->bufsize)
mb->head = 0;
transferred += len;
}
}
return transferred;
}
/*--------------- private memio functions -----------------------*/
static PRStatus PR_CALLBACK memio_Close(PRFileDesc *fd) {
struct PRFilePrivate *secret = fd->secret;
memio_buffer_destroy(&secret->readbuf);
memio_buffer_destroy(&secret->writebuf);
free(secret);
fd->dtor(fd);
return PR_SUCCESS;
}
static PRStatus PR_CALLBACK memio_Shutdown(PRFileDesc *fd, PRIntn how) {
/* TODO: pass shutdown status to app somehow */
return PR_SUCCESS;
}
/* If there was a network error in the past taking bytes
* out of the buffer, return it to the next call that
* tries to read from an empty buffer.
*/
static int PR_CALLBACK memio_Recv(PRFileDesc *fd,
uint8_t *buf,
PRInt32 len,
PRIntn flags,
PRIntervalTime timeout) {
struct PRFilePrivate *secret;
struct memio_buffer *mb;
int rv;
if (flags) {
PR_SetError(PR_NOT_IMPLEMENTED_ERROR, 0);
return -1;
}
secret = fd->secret;
mb = &secret->readbuf;
PR_ASSERT(mb->bufsize);
rv = memio_buffer_get(mb, buf, len);
if (rv == 0 && !secret->eof) {
secret->read_requested = len;
/* If there is no more data in the buffer, report any pending errors
* that were previously observed. Note that both the readbuf and the
* writebuf are checked for errors, since the application may have
* encountered a socket error while writing that would otherwise not
* be reported until the application attempted to write again - which
* it may never do.
*/
if (mb->last_err)
PR_SetError(mb->last_err, 0);
else if (secret->writebuf.last_err)
PR_SetError(secret->writebuf.last_err, 0);
else
PR_SetError(PR_WOULD_BLOCK_ERROR, 0);
return -1;
}
secret->read_requested = 0;
return rv;
}
static int PR_CALLBACK memio_Read(PRFileDesc *fd, uint8_t *buf, PRInt32 len) {
/* pull bytes from buffer */
return memio_Recv(fd, buf, len, 0, PR_INTERVAL_NO_TIMEOUT);
}
static int PR_CALLBACK memio_Send(PRFileDesc *fd,
const uint8_t *buf,
PRInt32 len,
PRIntn flags,
PRIntervalTime timeout) {
struct PRFilePrivate *secret;
struct memio_buffer *mb;
int rv;
secret = fd->secret;
mb = &secret->writebuf;
PR_ASSERT(mb->bufsize);
/* Note that the read error state is not reported, because it cannot be
* reported until all buffered data has been read. If there is an error
* with the next layer, attempting to call Send again will report the
* error appropriately.
*/
if (mb->last_err) {
PR_SetError(mb->last_err, 0);
return -1;
}
rv = memio_buffer_put(mb, buf, len);
if (rv == 0) {
PR_SetError(PR_WOULD_BLOCK_ERROR, 0);
return -1;
}
return rv;
}
static int PR_CALLBACK memio_Write(PRFileDesc *fd,
const uint8_t *buf,
PRInt32 len) {
/* append bytes to buffer */
return memio_Send(fd, buf, len, 0, PR_INTERVAL_NO_TIMEOUT);
}
static PRStatus PR_CALLBACK memio_GetPeerName(PRFileDesc *fd, PRNetAddr *addr) {
/* TODO: fail if memio_SetPeerName has not been called */
struct PRFilePrivate *secret = fd->secret;
*addr = secret->peername;
return PR_SUCCESS;
}
static PRStatus memio_GetSocketOption(PRFileDesc *fd,
PRSocketOptionData *data) {
/*
* Even in the original version for real tcp sockets,
* PR_SockOpt_Nonblocking is a special case that does not
* translate to a getsockopt() call
*/
if (PR_SockOpt_Nonblocking == data->option) {
data->value.non_blocking = PR_TRUE;
return PR_SUCCESS;
}
PR_SetError(PR_OPERATION_NOT_SUPPORTED_ERROR, 0);
return PR_FAILURE;
}
/*--------------- private memio data -----------------------*/
/*
* Implement just the bare minimum number of methods needed to make ssl happy.
*
* Oddly, PR_Recv calls ssl_Recv calls ssl_SocketIsBlocking calls
* PR_GetSocketOption, so we have to provide an implementation of
* PR_GetSocketOption that just says "I'm nonblocking".
*/
static struct PRIOMethods memio_layer_methods = {
PR_DESC_LAYERED,
memio_Close,
(PRReadFN)memio_Read,
(PRWriteFN)memio_Write,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
memio_Shutdown,
(PRRecvFN)memio_Recv,
(PRSendFN)memio_Send,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
memio_GetPeerName,
NULL,
NULL,
memio_GetSocketOption,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
};
static PRDescIdentity memio_identity = PR_INVALID_IO_LAYER;
static PRStatus memio_InitializeLayerName(void) {
memio_identity = PR_GetUniqueIdentity("memio");
return PR_SUCCESS;
}
/*--------------- public memio functions -----------------------*/
PRFileDesc *memio_CreateIOLayer(int readbufsize, int writebufsize) {
PRFileDesc *fd;
struct PRFilePrivate *secret;
static PRCallOnceType once;
PR_CallOnce(&once, memio_InitializeLayerName);
fd = PR_CreateIOLayerStub(memio_identity, &memio_layer_methods);
secret = static_cast<PRFilePrivate*>(malloc(sizeof(struct PRFilePrivate)));
memset(secret, 0, sizeof(*secret));
memio_buffer_new(&secret->readbuf, readbufsize);
memio_buffer_new(&secret->writebuf, writebufsize);
fd->secret = secret;
return fd;
}
void memio_SetPeerName(PRFileDesc* fd, const PRNetAddr* peername) {
PRFileDesc *memiofd = PR_GetIdentitiesLayer(fd, memio_identity);
struct PRFilePrivate *secret = memiofd->secret;
secret->peername = *peername;
}
memio_Private* memio_GetSecret(PRFileDesc* fd) {
PRFileDesc* memiofd = PR_GetIdentitiesLayer(fd, memio_identity);
struct PRFilePrivate *secret = memiofd->secret;
return reinterpret_cast<memio_Private*>(secret);
}
int memio_GetReadRequest(memio_Private *secret) {
return reinterpret_cast<PRFilePrivate*>(secret)->read_requested;
}
int memio_GetReadParams(memio_Private* secret, uint8_t** buf) {
struct memio_buffer* mb =
&(reinterpret_cast<PRFilePrivate*>(secret)->readbuf);
PR_ASSERT(mb->bufsize);
*buf = &mb->buf[mb->tail];
return memio_buffer_unused_contiguous(mb);
}
int memio_GetReadableBufferSize(memio_Private *secret) {
struct memio_buffer* mb =
&(reinterpret_cast<PRFilePrivate*>(secret)->readbuf);
PR_ASSERT(mb->bufsize);
return memio_buffer_used_contiguous(mb);
}
void memio_PutReadResult(memio_Private *secret, int bytes_read) {
struct memio_buffer* mb =
&(reinterpret_cast<PRFilePrivate*>(secret)->readbuf);
PR_ASSERT(mb->bufsize);
if (bytes_read > 0) {
mb->tail += bytes_read;
if (mb->tail == mb->bufsize)
mb->tail = 0;
} else if (bytes_read == 0) {
/* Record EOF condition and report to caller when buffer runs dry */
reinterpret_cast<PRFilePrivate*>(secret)->eof = PR_TRUE;
} else /* if (bytes_read < 0) */ {
mb->last_err = bytes_read;
}
}
int memio_GetWriteParams(memio_Private *secret,
const uint8_t** buf1, unsigned int *len1,
const uint8_t** buf2, unsigned int *len2) {
struct memio_buffer* mb =
&(reinterpret_cast<PRFilePrivate*>(secret)->writebuf);
PR_ASSERT(mb->bufsize);
if (mb->last_err)
return mb->last_err;
*buf1 = &mb->buf[mb->head];
*len1 = memio_buffer_used_contiguous(mb);
*buf2 = mb->buf;
*len2 = memio_buffer_wrapped_bytes(mb);
return 0;
}
void memio_PutWriteResult(memio_Private *secret, int bytes_written) {
struct memio_buffer* mb =
&(reinterpret_cast<PRFilePrivate*>(secret)->writebuf);
PR_ASSERT(mb->bufsize);
if (bytes_written > 0) {
mb->head += bytes_written;
if (mb->head >= mb->bufsize)
mb->head -= mb->bufsize;
} else if (bytes_written < 0) {
mb->last_err = bytes_written;
}
}
/*--------------- private memio_buffer self-test -----------------*/
/* Even a trivial unit test is very helpful when doing circular buffers. */
/*#define TRIVIAL_SELF_TEST*/
#ifdef TRIVIAL_SELF_TEST
#define TEST_BUFLEN 7
#define CHECKEQ(a, b) { \
if ((a) != (b)) { \
printf("%d != %d, Test failed line %d\n", a, b, __LINE__); \
exit(1); \
} \
}
#define FROM_STR(a) reinterpret_cast<const uint8_t*>(a)
int main() {
struct memio_buffer mb;
uint8_t buf[100];
int i;
memio_buffer_new(&mb, TEST_BUFLEN);
CHECKEQ(memio_buffer_unused_contiguous(&mb), TEST_BUFLEN-1);
CHECKEQ(memio_buffer_used_contiguous(&mb), 0);
CHECKEQ(memio_buffer_put(&mb, FROM_STR("howdy"), 5), 5);
CHECKEQ(memio_buffer_unused_contiguous(&mb), TEST_BUFLEN-1-5);
CHECKEQ(memio_buffer_used_contiguous(&mb), 5);
CHECKEQ(memio_buffer_wrapped_bytes(&mb), 0);
CHECKEQ(memio_buffer_put(&mb, FROM_STR("!"), 1), 1);
CHECKEQ(memio_buffer_unused_contiguous(&mb), 0);
CHECKEQ(memio_buffer_used_contiguous(&mb), 6);
CHECKEQ(memio_buffer_wrapped_bytes(&mb), 0);
CHECKEQ(memio_buffer_get(&mb, buf, 6), 6);
CHECKEQ(memcmp(buf, FROM_STR("howdy!"), 6), 0);
CHECKEQ(memio_buffer_unused_contiguous(&mb), 1);
CHECKEQ(memio_buffer_used_contiguous(&mb), 0);
CHECKEQ(memio_buffer_put(&mb, FROM_STR("01234"), 5), 5);
CHECKEQ(memio_buffer_used_contiguous(&mb), 1);
CHECKEQ(memio_buffer_wrapped_bytes(&mb), 4);
CHECKEQ(memio_buffer_unused_contiguous(&mb), TEST_BUFLEN-1-5);
CHECKEQ(memio_buffer_put(&mb, FROM_STR("5"), 1), 1);
CHECKEQ(memio_buffer_unused_contiguous(&mb), 0);
CHECKEQ(memio_buffer_used_contiguous(&mb), 1);
/* TODO: add more cases */
printf("Test passed\n");
exit(0);
}
#endif

View File

@ -1,111 +0,0 @@
// Copyright (c) 2011 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// Written in NSPR style to also be suitable for adding to the NSS demo suite
// Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
// This file is a modified copy of Chromium's src/net/base/nss_memio.h.
// char* has been changed to uint8_t* everywhere, and C++ casts are used.
// Revision 291806 (this should agree with "nss_rev" in DEPS).
#ifndef BIN_NET_NSS_MEMIO_H_
#define BIN_NET_NSS_MEMIO_H_
#include <stddef.h>
#include "vm/globals.h"
#ifdef __cplusplus
extern "C" {
#endif
#include "prio.h"
/* Opaque structure. Really just a more typesafe alias for PRFilePrivate. */
struct memio_Private;
typedef struct memio_Private memio_Private;
/*----------------------------------------------------------------------
NSPR I/O layer that terminates in a pair of circular buffers
rather than talking to the real network.
To use this with NSS:
1) call memio_CreateIOLayer to create a fake NSPR socket
2) call SSL_ImportFD to ssl-ify the socket
3) Do your own networking calls to set up a TCP connection
4) call memio_SetPeerName to tell NSS about the other end of the connection
5) While at the same time doing plaintext nonblocking NSPR I/O as
usual to the nspr file descriptor returned by SSL_ImportFD,
your app must shuttle encrypted data between
the real network and memio's network buffers.
memio_GetReadParams/memio_PutReadResult
are the hooks you need to pump data into memio's input buffer,
and memio_GetWriteParams/memio_PutWriteResult
are the hooks you need to pump data out of memio's output buffer.
----------------------------------------------------------------------*/
/* Create the I/O layer and its two circular buffers. */
PRFileDesc *memio_CreateIOLayer(int readbufsize, int writebufsize);
/* Must call before trying to make an ssl connection */
void memio_SetPeerName(PRFileDesc *fd, const PRNetAddr *peername);
/* Return a private pointer needed by the following
* four functions. (We could have passed a PRFileDesc to
* them, but that would be slower. Better for the caller
* to grab the pointer once and cache it.
* This may be a premature optimization.)
*/
memio_Private *memio_GetSecret(PRFileDesc *fd);
/* Ask memio how many bytes were requested by a higher layer if the
* last attempt to read data resulted in PR_WOULD_BLOCK_ERROR, due to the
* transport buffer being empty. If the last attempt to read data from the
* memio did not result in PR_WOULD_BLOCK_ERROR, returns 0.
*/
int memio_GetReadRequest(memio_Private *secret);
/* Ask memio where to put bytes from the network, and how many it can handle.
* Returns bytes available to write, or 0 if none available.
* Puts current buffer position into *buf.
*/
int memio_GetReadParams(memio_Private *secret, uint8_t **buf);
/* Ask memio how many bytes are contained in the internal buffer.
* Returns bytes available to read, or 0 if none available.
*/
int memio_GetReadableBufferSize(memio_Private *secret);
/* Tell memio how many bytes were read from the network.
* If bytes_read is 0, causes EOF to be reported to
* NSS after it reads the last byte from the circular buffer.
* If bytes_read is < 0, it is treated as an NSPR error code.
* See nspr/pr/src/md/unix/unix_errors.c for how to
* map from Unix errors to NSPR error codes.
* On EWOULDBLOCK or the equivalent, don't call this function.
*/
void memio_PutReadResult(memio_Private *secret, int bytes_read);
/* Ask memio what data it has to send to the network.
* If there was previous a write error, the NSPR error code is returned.
* Otherwise, it returns 0 and provides up to two buffers of data by
* writing the positions and lengths into |buf1|, |len1| and |buf2|, |len2|.
*/
int memio_GetWriteParams(memio_Private *secret,
const uint8_t **buf1, unsigned int *len1,
const uint8_t **buf2, unsigned int *len2);
/* Tell memio how many bytes were sent to the network.
* If bytes_written is < 0, it is treated as an NSPR error code.
* See nspr/pr/src/md/unix/unix_errors.c for how to
* map from Unix errors to NSPR error codes.
* On EWOULDBLOCK or the equivalent, don't call this function.
*/
void memio_PutWriteResult(memio_Private *secret, int bytes_written);
#ifdef __cplusplus
}
#endif
#endif // BIN_NET_NSS_MEMIO_H_

View File

@ -1,9 +0,0 @@
// Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
#ifdef __i386__
#include "../../../third_party/nss/nspr/pr/src/md/unix/os_Linux_x86.s"
#elif defined(__x86_64__)
#include "../../../third_party/nss/nspr/pr/src/md/unix/os_Linux_x86_64.s"
#endif

View File

@ -1,11 +0,0 @@
// Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
#if !defined(_MSC_VER)
#error "This file should only be compiled under MSVC"
#endif
#if defined(_X86_)
#include "../../../third_party/nss/nss/lib/freebl/mpi/mpi_x86_asm.c"
#endif

View File

@ -1,226 +0,0 @@
# Copyright (c) 2012 The Chromium Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
# Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file
# for details. All rights reserved. Use of this source code is governed by a
# BSD-style license that can be found in the LICENSE file.
# This file is a modified copy of Chromium's src/third_party/sqlite/sqlite.gyp.
# Revision 291806 (this should agree with "nss_rev" in DEPS).
{
# Added by Dart. All Dart comments refer to the following block or line.
'includes': [
'../../tools/gyp/runtime-configurations.gypi',
'../../tools/gyp/nss_configurations.gypi',
],
'variables': {
# Added by Dart.
'sqlite_directory': '../../../third_party/sqlite',
'use_system_sqlite%': 0,
'required_sqlite_version': '3.6.1',
},
'target_defaults': {
'defines': [
'SQLITE_CORE',
'SQLITE_ENABLE_BROKEN_FTS2',
'SQLITE_ENABLE_FTS2',
'SQLITE_ENABLE_FTS3',
# Disabled by Dart: An external module with advanced unicode functions.
# 'SQLITE_ENABLE_ICU',
'SQLITE_ENABLE_MEMORY_MANAGEMENT',
'SQLITE_SECURE_DELETE',
'SQLITE_SEPARATE_CACHE_POOLS',
'THREADSAFE',
'_HAS_EXCEPTIONS=0',
],
},
# Added by Dart. We do not indent, so diffs with the original are clearer.
'conditions': [[ 'dart_io_support==1', {
'targets': [
{
'target_name': 'sqlite_dart', # Added by Dart (the _dart postfix)
'toolsets':['host','target'],
'conditions': [
[ 'chromeos==1' , {
'defines': [
# Despite obvious warnings about not using this flag
# in deployment, we are turning off sync in ChromeOS
# and relying on the underlying journaling filesystem
# to do error recovery properly. It's much faster.
'SQLITE_NO_SYNC',
],
},
],
['use_system_sqlite', {
'type': 'none',
'direct_dependent_settings': {
'defines': [
'USE_SYSTEM_SQLITE',
],
},
'conditions': [
['OS == "ios"', {
'dependencies': [
'sqlite_regexp',
],
'link_settings': {
'libraries': [
'$(SDKROOT)/usr/lib/libsqlite3.dylib',
],
},
}],
['os_posix == 1 and OS != "mac" and OS != "ios" and OS != "android"', {
'direct_dependent_settings': {
'cflags': [
# This next command produces no output but it it will fail
# (and cause GYP to fail) if we don't have a recent enough
# version of sqlite.
'<!@(pkg-config --atleast-version=<(required_sqlite_version) sqlite3)',
'<!@(pkg-config --cflags sqlite3)',
],
},
'link_settings': {
'ldflags': [
'<!@(pkg-config --libs-only-L --libs-only-other sqlite3)',
],
'libraries': [
'<!@(pkg-config --libs-only-l sqlite3)',
],
},
}],
],
}, { # !use_system_sqlite
'product_name': 'sqlite3',
'type': 'static_library',
# Changed by Dart: '<(sqlite_directory)/' added to all paths.
'sources': [
'<(sqlite_directory)/amalgamation/sqlite3.h',
'<(sqlite_directory)/amalgamation/sqlite3.c',
# fts2.c currently has a lot of conflicts when added to
# the amalgamation. It is probably not worth fixing that.
'<(sqlite_directory)/src/ext/fts2/fts2.c',
'<(sqlite_directory)/src/ext/fts2/fts2.h',
'<(sqlite_directory)/src/ext/fts2/fts2_hash.c',
'<(sqlite_directory)/src/ext/fts2/fts2_hash.h',
'<(sqlite_directory)/src/ext/fts2/fts2_icu.c',
'<(sqlite_directory)/src/ext/fts2/fts2_porter.c',
'<(sqlite_directory)/src/ext/fts2/fts2_tokenizer.c',
'<(sqlite_directory)/src/ext/fts2/fts2_tokenizer.h',
'<(sqlite_directory)/src/ext/fts2/fts2_tokenizer1.c',
],
# TODO(shess): Previously fts1 and rtree files were
# explicitly excluded from the build. Make sure they are
# logically still excluded.
# TODO(shess): Should all of the sources be listed and then
# excluded? For editing purposes?
'include_dirs': [
'<(sqlite_directory)/amalgamation',
# Needed for fts2 to build.
'<(sqlite_directory)/src/src',
],
'dependencies': [
# Disabled by Dart.
# '../icu/icu.gyp:icui18n',
# Disabled by Dart.
# '../icu/icu.gyp:icuuc',
],
'direct_dependent_settings': {
'include_dirs': [
'<(sqlite_directory)/.',
'<(sqlite_directory)/../..',
],
},
'msvs_disabled_warnings': [
4018, 4244, 4267,
],
'variables': {
'clang_warning_flags': [
# sqlite does `if (*a++ && *b++);` in a non-buggy way.
'-Wno-empty-body',
# sqlite has some `unsigned < 0` checks.
'-Wno-tautological-compare',
],
},
'conditions': [
['OS=="linux"', {
'link_settings': {
'libraries': [
'-ldl',
],
},
}],
['OS == "mac" or OS == "ios"', {
'link_settings': {
'libraries': [
'$(SDKROOT)/System/Library/Frameworks/CoreFoundation.framework',
],
},
}],
['OS == "android"', {
'defines': [
'HAVE_USLEEP=1',
'SQLITE_DEFAULT_JOURNAL_SIZE_LIMIT=1048576',
'SQLITE_DEFAULT_AUTOVACUUM=1',
'SQLITE_TEMP_STORE=3',
'SQLITE_ENABLE_FTS3_BACKWARDS',
'DSQLITE_DEFAULT_FILE_FORMAT=4',
],
}],
['os_posix == 1 and OS != "mac" and OS != "android"', {
'cflags': [
# SQLite doesn't believe in compiler warnings,
# preferring testing.
# http://www.sqlite.org/faq.html#q17
'-Wno-int-to-pointer-cast',
'-Wno-pointer-to-int-cast',
],
}],
],
}],
],
},
],
'conditions': [
['os_posix == 1 and OS != "mac" and OS != "ios" and OS != "android" and not use_system_sqlite', {
'targets': [
{
'target_name': 'sqlite_shell_dart', # Added by Dart (the _dart postfix)
'type': 'executable',
'dependencies': [
# Disabled by Dart.
# '../icu/icu.gyp:icuuc',
'sqlite_dart', # Added by Dart (the _dart postfix)
],
'sources': [
'<(sqlite_directory)/src/src/shell.c',
'<(sqlite_directory)/src/src/shell_icu_linux.c',
# Include a dummy c++ file to force linking of libstdc++.
'<(sqlite_directory)/build_as_cpp.cc',
],
},
],
},],
['OS == "ios"', {
'targets': [
{
'target_name': 'sqlite_regexp',
'type': 'static_library',
'dependencies': [
'../icu/icu.gyp:icui18n',
'../icu/icu.gyp:icuuc',
],
'sources': [
'src/ext/icu/icu.c',
],
},
],
}],
],
}]],
}

View File

@ -1,216 +0,0 @@
# Copyright (c) 2012 The Chromium Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
# Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file
# for details. All rights reserved. Use of this source code is governed by a
# BSD-style license that can be found in the LICENSE file.
# This file is a modified copy of Chromium's src/net/third_party/nss/ssl.gyp.
# Revision 291806 (this should agree with "nss_rev" in DEPS).
# The following modification was made to make sure we have the same
# xcode_settings on all configurations (otherwise we can't build with ninja):
# 'configurations': {
# 'Debug_Base': {
# + 'inherit_from': ['Dart_Base'],
# 'defines': [
# 'DEBUG',
# ],
# },
# },
{
# Conditions section for ssl-bodge (Compiling SSL on linux using system
# NSS and NSPR libraries) removed:
# 'conditions': [
# [ 'os_posix == 1 and OS != "mac" and OS != "ios"', {
# ...
# }]],
# Added by Dart. All Dart comments refer to the following block or line.
'includes': [
'../../tools/gyp/runtime-configurations.gypi',
'../../tools/gyp/nss_configurations.gypi',
],
# Added by Dart.
'variables': {
'ssl_directory': '../../../third_party/net_nss',
'os_posix': 0,
},
# Added by Dart. We do not indent, so diffs with the original are clearer.
'conditions': [[ 'dart_io_support==1', {
'targets': [
{
'target_name': 'libssl_dart', # Added by Dart (the _dart postfix)
'type': 'static_library',
'toolsets':['host','target'],
# Changed by Dart: '<(ssl_directory)/' added to all paths.
'sources': [
'<(ssl_directory)/ssl/authcert.c',
'<(ssl_directory)/ssl/cmpcert.c',
'<(ssl_directory)/ssl/derive.c',
'<(ssl_directory)/ssl/dtlscon.c',
'<(ssl_directory)/ssl/os2_err.c',
'<(ssl_directory)/ssl/os2_err.h',
'<(ssl_directory)/ssl/preenc.h',
'<(ssl_directory)/ssl/prelib.c',
'<(ssl_directory)/ssl/ssl.h',
'<(ssl_directory)/ssl/ssl3con.c',
'<(ssl_directory)/ssl/ssl3ecc.c',
'<(ssl_directory)/ssl/ssl3ext.c',
'<(ssl_directory)/ssl/ssl3gthr.c',
'<(ssl_directory)/ssl/ssl3prot.h',
'<(ssl_directory)/ssl/sslauth.c',
'<(ssl_directory)/ssl/sslcon.c',
'<(ssl_directory)/ssl/ssldef.c',
'<(ssl_directory)/ssl/sslenum.c',
'<(ssl_directory)/ssl/sslerr.c',
'<(ssl_directory)/ssl/sslerr.h',
'<(ssl_directory)/ssl/SSLerrs.h',
'<(ssl_directory)/ssl/sslerrstrs.c',
'<(ssl_directory)/ssl/sslgathr.c',
'<(ssl_directory)/ssl/sslimpl.h',
'<(ssl_directory)/ssl/sslinfo.c',
'<(ssl_directory)/ssl/sslinit.c',
'<(ssl_directory)/ssl/sslmutex.c',
'<(ssl_directory)/ssl/sslmutex.h',
'<(ssl_directory)/ssl/sslnonce.c',
'<(ssl_directory)/ssl/sslplatf.c',
'<(ssl_directory)/ssl/sslproto.h',
'<(ssl_directory)/ssl/sslreveal.c',
'<(ssl_directory)/ssl/sslsecur.c',
'<(ssl_directory)/ssl/sslsnce.c',
'<(ssl_directory)/ssl/sslsock.c',
'<(ssl_directory)/ssl/sslt.h',
'<(ssl_directory)/ssl/ssltrace.c',
'<(ssl_directory)/ssl/sslver.c',
'<(ssl_directory)/ssl/unix_err.c',
'<(ssl_directory)/ssl/unix_err.h',
'<(ssl_directory)/ssl/win32err.c',
'<(ssl_directory)/ssl/win32err.h',
# Changed by Dart: All files under '<(ssl_directory)/ssl/bodge' removed.
],
# Changed by Dart: '<(ssl_directory)/' added to all paths.
'sources!': [
'<(ssl_directory)/ssl/os2_err.c',
'<(ssl_directory)/ssl/os2_err.h',
],
'defines': [
'NO_PKCS11_BYPASS',
'NSS_ENABLE_ECC',
'USE_UTIL_DIRECTLY',
],
'defines!': [
'DEBUG',
],
'dependencies': [
# Changed by Dart.
'zlib.gyp:zlib_dart', # Added by Dart (the _dart postfix)
# Dart: Start of copy of code from 'bodge' conditions section below.
'nss.gyp:nspr_dart', # Added by Dart (the _dart postfix)
'nss.gyp:nss_dart', # Added by Dart (the _dart postfix)
],
'export_dependent_settings': [
'nss.gyp:nspr_dart', # Added by Dart (the _dart postfix)
'nss.gyp:nss_dart', # Added by Dart (the _dart postfix)
],
'direct_dependent_settings': {
'include_dirs': [
'<(ssl_directory)/ssl',
],
'defines': [
'NSS_PLATFORM_CLIENT_AUTH',
],
# Dart: End of copy of code from bodge conditions section.
},
'msvs_disabled_warnings': [4018, 4244, 4267],
'conditions': [
['component == "shared_library"', {
'conditions': [
['OS == "mac" or OS == "ios"', {
'xcode_settings': {
'GCC_SYMBOLS_PRIVATE_EXTERN': 'NO',
},
}],
['OS == "win"', {
'sources': [
'ssl/exports_win.def',
],
}],
['os_posix == 1 and OS != "mac" and OS != "ios"', {
'cflags!': ['-fvisibility=hidden'],
}],
],
}],
[ 'clang == 1', {
'cflags': [
# See http://crbug.com/138571#c8. In short, sslsecur.c picks up the
# system's cert.h because cert.h isn't in chromium's repo.
'-Wno-incompatible-pointer-types',
# There is a broken header guard in /usr/include/nss/secmod.h:
# https://bugzilla.mozilla.org/show_bug.cgi?id=884072
'-Wno-header-guard',
],
}],
[ 'OS == "linux"', {
'link_settings': {
'libraries': [
'-ldl',
],
},
# Added by Dart.
'defines': [
'XP_UNIX',
'NSS_PLATFORM_CLIENT_AUTH',
'NSS_USE_STATIC_LIBS',
],
}],
[ 'OS == "mac" or OS == "ios"', {
'defines': [
'XP_UNIX',
'DARWIN',
'XP_MACOSX',
],
}],
[ 'OS == "mac"', {
'link_settings': {
'libraries': [
'$(SDKROOT)/System/Library/Frameworks/Security.framework',
],
},
}],
[ 'OS == "win"', {
'sources!': [
'<(ssl_directory)/ssl/unix_err.c',
'<(ssl_directory)/ssl/unix_err.h',
],
},
{ # else: OS != "win"
'sources!': [
'<(ssl_directory)/ssl/win32err.c',
'<(ssl_directory)/ssl/win32err.h',
],
},
],
# Dart: Conditions sections for ssl/bodge removed.
# [ 'os_posix == 1 and OS != "mac" and OS != "ios", {
# ...
# ],
# [ 'OS == "mac" or OS == "ios" or OS == "win"', {
# ...
# ],
],
'configurations': {
'Debug_Base': {
'inherit_from': ['Dart_Base'],
'defines': [
'DEBUG',
],
},
},
},
],
}]],
}

File diff suppressed because it is too large Load Diff

View File

@ -5,19 +5,19 @@
#ifndef BIN_SECURE_SOCKET_H_
#define BIN_SECURE_SOCKET_H_
#ifdef DART_IO_SECURE_SOCKET_DISABLED
#error "secure_socket.h can only be included on builds with SSL enabled"
#endif
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include <sys/types.h>
#if !defined(DART_IO_SECURE_SOCKET_DISABLED)
#include <prinit.h>
#include <prerror.h>
#include <prnetdb.h>
#include <ssl.h>
#else
struct PRFileDesc;
#endif
#include <openssl/bio.h>
#include <openssl/ssl.h>
#include <openssl/err.h>
#include <openssl/x509.h>
#include "bin/builtin.h"
#include "bin/dartutils.h"
@ -28,6 +28,10 @@ struct PRFileDesc;
namespace dart {
namespace bin {
/* These are defined in root_certificates.cc. */
extern const unsigned char* root_certificates_pem;
extern unsigned int root_certificates_pem_length;
/*
* SSLFilter encapsulates the NSS SSL(TLS) code in a filter, that communicates
* with the containing _SecureFilterImpl Dart object through four shared
@ -49,20 +53,18 @@ class SSLFilter {
SSLFilter()
: callback_error(NULL),
ssl_(NULL),
string_start_(NULL),
string_length_(NULL),
handshake_complete_(NULL),
bad_certificate_callback_(NULL),
in_handshake_(false),
client_certificate_name_(NULL),
filter_(NULL) { }
hostname_(NULL) { }
void Init(Dart_Handle dart_this);
void Connect(const char* host,
const RawAddr& raw_addr,
int port,
void Connect(const char* hostname,
SSL_CTX* context,
bool is_server,
const char* certificate_name,
bool request_client_certificate,
bool require_client_certificate,
bool send_client_certificate,
@ -78,27 +80,29 @@ class SSLFilter {
Dart_Handle bad_certificate_callback() {
return Dart_HandleFromPersistent(bad_certificate_callback_);
}
intptr_t ProcessReadPlaintextBuffer(int start, int end);
intptr_t ProcessWritePlaintextBuffer(int start1, int end1,
int start2, int end2);
intptr_t ProcessReadEncryptedBuffer(int start, int end);
intptr_t ProcessWriteEncryptedBuffer(int start, int end);
int ProcessReadPlaintextBuffer(int start, int end);
int ProcessWritePlaintextBuffer(int start, int end);
int ProcessReadEncryptedBuffer(int start, int end);
int ProcessWriteEncryptedBuffer(int start, int end);
bool ProcessAllBuffers(int starts[kNumBuffers],
int ends[kNumBuffers],
bool in_handshake);
Dart_Handle PeerCertificate();
static void InitializeLibrary(const char* certificate_database,
const char* password,
bool use_builtin_root_certificates,
bool report_duplicate_initialization = true);
static void InitializeLibrary();
Dart_Handle callback_error;
static CObject* ProcessFilterRequest(const CObjectArray& request);
// The index of the external data field in _ssl that points to the SSLFilter.
static int filter_ssl_index;
// TODO(whesse): make private:
SSL* ssl_;
BIO* socket_side_;
private:
static const int kMemioBufferSize = 20 * KB;
static bool library_initialized_;
static const char* password_;
static Mutex* mutex_; // To protect library initialization.
uint8_t* buffers_[kNumBuffers];
@ -111,8 +115,8 @@ class SSLFilter {
Dart_PersistentHandle bad_certificate_callback_;
bool in_handshake_;
bool is_server_;
char* client_certificate_name_;
PRFileDesc* filter_;
char* hostname_;
X509_VERIFY_PARAM* certificate_checking_parameters_;
static bool isBufferEncrypted(int i) {
return static_cast<BufferIndex>(i) >= kFirstEncrypted;

View File

@ -5,11 +5,6 @@
patch class SecureSocket {
/* patch */ factory SecureSocket._(RawSecureSocket rawSocket) =>
new _SecureSocket(rawSocket);
/* patch */ static void initialize({String database,
String password,
bool useBuiltinRoots: true})
native "SecureSocket_InitializeLibrary";
}
@ -17,6 +12,9 @@ patch class _SecureFilter {
/* patch */ factory _SecureFilter() => new _SecureFilterImpl();
}
patch class X509Certificate {
/* patch */ factory X509Certificate._() => new _X509CertificateImpl();
}
class _SecureSocket extends _Socket implements SecureSocket {
_SecureSocket(RawSecureSocket raw) : super(raw);
@ -79,10 +77,8 @@ class _SecureFilterImpl
}
void connect(String hostName,
Uint8List sockaddrStorage,
int port,
SecurityContext context,
bool is_server,
String certificateName,
bool requestClientCertificate,
bool requireClientCertificate,
bool sendClientCertificate,
@ -119,3 +115,68 @@ class _SecureFilterImpl
List<_ExternalBuffer> buffers;
}
patch class SecurityContext {
/* patch */ factory SecurityContext() {
return new _SecurityContext();
}
/* patch */ static SecurityContext get defaultContext {
return _SecurityContext.defaultContext;
}
}
class _SecurityContext
extends NativeFieldWrapperClass1
implements SecurityContext {
_SecurityContext() {
_createNativeContext();
}
void _createNativeContext() native "SecurityContext_Allocate";
static final SecurityContext defaultContext =
new _SecurityContext().._trustBuiltinRoots();
void usePrivateKey(String keyFile, {String password})
native "SecurityContext_UsePrivateKey";
void setTrustedCertificates({String file, String directory})
native "SecurityContext_SetTrustedCertificates";
void useCertificateChain(String file)
native "SecurityContext_UseCertificateChain";
void setClientAuthorities(String file)
native "SecurityContext_SetClientAuthorities";
void setAlpnProtocols(List<String> protocols, bool isServer) {
Uint8List encodedProtocols =
SecurityContext._protocolsToLengthEncoding(protocols);
_setAlpnProtocols(encodedProtocols, isServer);
}
void _setAlpnProtocols(Uint8List protocols, bool isServer)
native "SecurityContext_SetAlpnProtocols";
void _trustBuiltinRoots()
native "SecurityContext_TrustBuiltinRoots";
}
/**
* _X509CertificateImpl wraps an X509 certificate object held by the BoringSSL
* library. It exposes the fields of the certificate object.
*/
class _X509CertificateImpl extends NativeFieldWrapperClass1
implements X509Certificate {
// The native field must be set manually on a new object, in native code.
// This is done by WrappedX509 in secure_socket.cc.
_X509CertificateImpl();
String get subject native "X509_Subject";
String get issuer native "X509_Issuer";
DateTime get startValidity {
return new DateTime.fromMillisecondsSinceEpoch(_startValidity(),
isUtc: true);
}
DateTime get endValidity {
return new DateTime.fromMillisecondsSinceEpoch(_endValidity(),
isUtc: true);
}
int _startValidity() native "X509_StartValidity";
int _endValidity() native "X509_EndValidity";
}

View File

@ -99,6 +99,66 @@ void FUNCTION_NAME(SecureSocket_NewServicePort)(Dart_NativeArguments args) {
"Secure Sockets unsupported on this platform"));
}
void FUNCTION_NAME(SecurityContext_Allocate)(Dart_NativeArguments args) {
Dart_ThrowException(DartUtils::NewDartArgumentError(
"Secure Sockets unsupported on this platform"));
}
void FUNCTION_NAME(SecurityContext_UsePrivateKey)(Dart_NativeArguments args) {
Dart_ThrowException(DartUtils::NewDartArgumentError(
"Secure Sockets unsupported on this platform"));
}
void FUNCTION_NAME(SecurityContext_SetAlpnProtocols)(
Dart_NativeArguments args) {
Dart_ThrowException(DartUtils::NewDartArgumentError(
"Secure Sockets unsupported on this platform"));
}
void FUNCTION_NAME(SecurityContext_SetClientAuthorities)(
Dart_NativeArguments args) {
Dart_ThrowException(DartUtils::NewDartArgumentError(
"Secure Sockets unsupported on this platform"));
}
void FUNCTION_NAME(SecurityContext_SetTrustedCertificates)(
Dart_NativeArguments args) {
Dart_ThrowException(DartUtils::NewDartArgumentError(
"Secure Sockets unsupported on this platform"));
}
void FUNCTION_NAME(SecurityContext_TrustBuiltinRoots)(
Dart_NativeArguments args) {
Dart_ThrowException(DartUtils::NewDartArgumentError(
"Secure Sockets unsupported on this platform"));
}
void FUNCTION_NAME(SecurityContext_UseCertificateChain)(
Dart_NativeArguments args) {
Dart_ThrowException(DartUtils::NewDartArgumentError(
"Secure Sockets unsupported on this platform"));
}
void FUNCTION_NAME(X509_Subject)(Dart_NativeArguments args) {
Dart_ThrowException(DartUtils::NewDartArgumentError(
"Secure Sockets unsupported on this platform"));
}
void FUNCTION_NAME(X509_Issuer)(Dart_NativeArguments args) {
Dart_ThrowException(DartUtils::NewDartArgumentError(
"Secure Sockets unsupported on this platform"));
}
void FUNCTION_NAME(X509_StartValidity)(Dart_NativeArguments args) {
Dart_ThrowException(DartUtils::NewDartArgumentError(
"Secure Sockets unsupported on this platform"));
}
void FUNCTION_NAME(X509_EndValidity)(Dart_NativeArguments args) {
Dart_ThrowException(DartUtils::NewDartArgumentError(
"Secure Sockets unsupported on this platform"));
}
class SSLFilter {
public:
static CObject* ProcessFilterRequest(const CObjectArray& request);

View File

@ -20,7 +20,7 @@ class OSError {
enum SubSystem {
kSystem,
kGetAddressInfo,
kNSS,
kBoringSSL,
kUnknown = -1
};

View File

@ -403,12 +403,26 @@ class SecureSocket {
factory SecureSocket._(RawSecureSocket rawSocket) {
throw new UnsupportedError("SecureSocket constructor");
}
}
@patch
class SecurityContext {
@patch
factory SecurityContext() {
throw new UnsupportedError("SecurityContext constructor");
}
@patch
static void initialize({String database,
String password,
bool useBuiltinRoots: true}) {
throw new UnsupportedError("SecureSocket.initialize");
static SecurityContext get defaultContext {
throw new UnsupportedError("default SecurityContext getter");
}
}
@patch
class X509Certificate {
@patch
factory X509Certificate._() {
throw new UnsupportedError("X509Certificate constructor");
}
}

View File

@ -93,23 +93,28 @@ abstract class HttpStatus {
*
* Use [bindSecure] to create an HTTPS server.
*
* The server presents a certificate to the client. In the following
* example, the certificate is named `localhost_cert` and comes from
* the database found in the `pkcert` directory.
* The server presents a certificate to the client. The certificate
* chain and the private key are set in the SecurityContext
* object that is passed to [bindSecure].
*
* import 'dart:io';
* import "dart:isolate";
*
* main() {
* var testPkcertDatabase = Platform.script.resolve('pkcert')
* .toFilePath();
* SecureSocket.initialize(database: testPkcertDatabase,
* password: 'dartdart');
* SecurityContext context = new SecurityContext();
* var chain =
* Platform.script.resolve('certificates/server_chain.pem')
* .toFilePath();
* var key =
* Platform.script.resolve('certificates/server_key.pem')
* .toFilePath();
* context.useCertificateChain(chain);
* context.usePrivateKey(key, password: 'dartdart');
*
* HttpServer
* .bindSecure(InternetAddress.ANY_IP_V6,
* 443,
* certificateName: 'localhost_cert')
* context)
* .then((server) {
* server.listen((HttpRequest request) {
* request.response.write('Hello, world!');
@ -118,10 +123,8 @@ abstract class HttpStatus {
* });
* }
*
* The certificate database is managed using the Mozilla certutil tool (see
* [NSS Tools certutil](https://developer.mozilla.org/en-US/docs/NSS/tools/NSS_Tools_certutil)).
* Dart uses the NSS library to handle SSL, and the Mozilla certutil
* must be used to manipulate the certificate database.
* The certificates and keys are pem files, which can be created and
* managed with the tools in OpenSSL and BoringSSL.
*
* ## Connect to a server socket
*
@ -291,6 +294,7 @@ abstract class HttpServer implements Stream<HttpRequest> {
static Future<HttpServer> bindSecure(address,
int port,
SecurityContext context,
{int backlog: 0,
bool v6Only: false,
String certificateName,
@ -298,6 +302,7 @@ abstract class HttpServer implements Stream<HttpRequest> {
bool shared: false})
=> _HttpServer.bindSecure(address,
port,
context,
backlog,
v6Only,
certificateName,
@ -1331,7 +1336,7 @@ abstract class HttpClient {
*/
String userAgent;
factory HttpClient() => new _HttpClient();
factory HttpClient({SecurityContext context}) => new _HttpClient(context);
/**
* Opens a HTTP connection.

View File

@ -1256,6 +1256,7 @@ class _HttpClientConnection {
final String key;
final Socket _socket;
final bool _proxyTunnel;
final SecurityContext _context;
final _HttpParser _httpParser;
StreamSubscription _subscription;
final _HttpClient _httpClient;
@ -1268,7 +1269,7 @@ class _HttpClientConnection {
Future _streamFuture;
_HttpClientConnection(this.key, this._socket, this._httpClient,
[this._proxyTunnel = false])
[this._proxyTunnel = false, this._context])
: _httpParser = new _HttpParser.responseParser() {
_httpParser.listenToStream(_socket);
@ -1496,7 +1497,10 @@ class _HttpClientConnection {
}
var socket = response._httpRequest._httpClientConnection._socket;
return SecureSocket.secure(
socket, host: host, onBadCertificate: callback);
socket,
host: host,
context: _context,
onBadCertificate: callback);
})
.then((secureSocket) {
String key = _HttpClientConnection.makeKey(true, host, port);
@ -1543,12 +1547,17 @@ class _ConnectionTarget {
final String host;
final int port;
final bool isSecure;
final SecurityContext context;
final Set<_HttpClientConnection> _idle = new HashSet();
final Set<_HttpClientConnection> _active = new HashSet();
final Queue _pending = new ListQueue();
int _connecting = 0;
_ConnectionTarget(this.key, this.host, this.port, this.isSecure);
_ConnectionTarget(this.key,
this.host,
this.port,
this.isSecure,
this.context);
bool get isEmpty => _idle.isEmpty && _active.isEmpty && _connecting == 0;
@ -1620,12 +1629,13 @@ class _ConnectionTarget {
return completer.future;
}
var currentBadCertificateCallback = client._badCertificateCallback;
bool callback(X509Certificate certificate) =>
callback(X509Certificate certificate) =>
currentBadCertificateCallback == null ? false :
currentBadCertificateCallback(certificate, uriHost, uriPort);
Future socketFuture = (isSecure && proxy.isDirect
? SecureSocket.connect(host,
port,
context: context,
sendClientCertificate: true,
onBadCertificate: callback)
: Socket.connect(host, port));
@ -1633,7 +1643,8 @@ class _ConnectionTarget {
return socketFuture.then((socket) {
_connecting--;
socket.setOption(SocketOption.TCP_NODELAY, true);
var connection = new _HttpClientConnection(key, socket, client);
var connection =
new _HttpClientConnection(key, socket, client, false, context);
if (isSecure && !proxy.isDirect) {
connection._dispose = true;
return connection.createProxyTunnel(uriHost, uriPort, proxy, callback)
@ -1662,6 +1673,7 @@ class _HttpClient implements HttpClient {
= new HashMap<String, _ConnectionTarget>();
final List<_Credentials> _credentials = [];
final List<_ProxyCredentials> _proxyCredentials = [];
final SecurityContext _context;
Function _authenticate;
Function _authenticateProxy;
Function _findProxy = HttpClient.findProxyFromEnvironment;
@ -1676,6 +1688,8 @@ class _HttpClient implements HttpClient {
String userAgent = _getHttpVersion();
_HttpClient(SecurityContext this._context);
void set idleTimeout(Duration timeout) {
_idleTimeout = timeout;
for (var c in _connectionTargets.values) {
@ -1894,8 +1908,9 @@ class _HttpClient implements HttpClient {
_ConnectionTarget _getConnectionTarget(String host, int port, bool isSecure) {
String key = _HttpClientConnection.makeKey(isSecure, host, port);
return _connectionTargets.putIfAbsent(
key, () => new _ConnectionTarget(key, host, port, isSecure));
return _connectionTargets.putIfAbsent(key, () {
return new _ConnectionTarget(key, host, port, isSecure, _context);
});
}
// Get a new _HttpClientConnection, from the matching _ConnectionTarget.
@ -2207,6 +2222,7 @@ class _HttpServer
static Future<HttpServer> bindSecure(address,
int port,
SecurityContext context,
int backlog,
bool v6Only,
String certificate_name,
@ -2215,7 +2231,7 @@ class _HttpServer
return SecureServerSocket.bind(
address,
port,
certificate_name,
context,
backlog: backlog,
v6Only: v6Only,
requestClientCertificate: requestClientCertificate,

View File

@ -232,11 +232,12 @@ part 'link.dart';
part 'platform.dart';
part 'platform_impl.dart';
part 'process.dart';
part 'secure_server_socket.dart';
part 'secure_socket.dart';
part 'security_context.dart';
part 'service_object.dart';
part 'socket.dart';
part 'stdio.dart';
part 'string_transformer.dart';
part 'secure_socket.dart';
part 'secure_server_socket.dart';
part 'websocket.dart';
part 'websocket_impl.dart';

View File

@ -27,11 +27,12 @@
'platform_impl.dart',
'process.dart',
'service_object.dart',
'secure_server_socket.dart',
'secure_socket.dart',
'security_context.dart',
'socket.dart',
'stdio.dart',
'string_transformer.dart',
'secure_socket.dart',
'secure_server_socket.dart',
'websocket.dart',
'websocket_impl.dart',
],

View File

@ -45,12 +45,6 @@ class SecureServerSocket extends Stream<SecureSocket> {
*
* [address] must be given as a numeric address, not a host name.
*
* [certificateName] is the nickname or the distinguished name (DN) of
* the certificate in the certificate database. It is looked up in the
* NSS certificate database set by SecureSocket.initialize.
* If [certificateName] contains "CN=", it is assumed to be a distinguished
* name. Otherwise, it is looked up as a nickname.
*
* To request or require that clients authenticate by providing an SSL (TLS)
* client certificate, set the optional parameter [requestClientCertificate]
* or [requireClientCertificate] to true. Requiring a certificate implies
@ -70,7 +64,7 @@ class SecureServerSocket extends Stream<SecureSocket> {
static Future<SecureServerSocket> bind(
address,
int port,
String certificateName,
SecurityContext context,
{int backlog: 0,
bool v6Only: false,
bool requestClientCertificate: false,
@ -80,7 +74,7 @@ class SecureServerSocket extends Stream<SecureSocket> {
return RawSecureServerSocket.bind(
address,
port,
certificateName,
context,
backlog: backlog,
v6Only: v6Only,
requestClientCertificate: requestClientCertificate,
@ -128,21 +122,20 @@ class SecureServerSocket extends Stream<SecureSocket> {
* See [RawSecureSocket] for more info.
*/
class RawSecureServerSocket extends Stream<RawSecureSocket> {
RawServerSocket _socket;
final RawServerSocket _socket;
StreamController<RawSecureSocket> _controller;
StreamSubscription<RawSocket> _subscription;
final String certificateName;
final SecurityContext _context;
final bool requestClientCertificate;
final bool requireClientCertificate;
final List<String> supportedProtocols;
bool _closed = false;
RawSecureServerSocket._(RawServerSocket serverSocket,
this.certificateName,
RawSecureServerSocket._(this._socket,
this._context,
this.requestClientCertificate,
this.requireClientCertificate,
this.supportedProtocols) {
_socket = serverSocket;
_controller = new StreamController<RawSecureSocket>(
sync: true,
onListen: _onSubscriptionStateChange,
@ -205,7 +198,7 @@ class RawSecureServerSocket extends Stream<RawSecureSocket> {
static Future<RawSecureServerSocket> bind(
address,
int port,
String certificateName,
SecurityContext context,
{int backlog: 0,
bool v6Only: false,
bool requestClientCertificate: false,
@ -216,7 +209,7 @@ class RawSecureServerSocket extends Stream<RawSecureSocket> {
address, port, backlog: backlog, v6Only: v6Only, shared: shared)
.then((serverSocket) => new RawSecureServerSocket._(
serverSocket,
certificateName,
context,
requestClientCertificate,
requireClientCertificate,
supportedProtocols));
@ -263,7 +256,7 @@ class RawSecureServerSocket extends Stream<RawSecureSocket> {
_RawSecureSocket.connect(
connection.address,
remotePort,
certificateName,
context: _context,
is_server: true,
socket: connection,
requestClientCertificate: requestClientCertificate,

View File

@ -18,16 +18,6 @@ abstract class SecureSocket implements Socket {
* [host] on port [port]. The returned Future will complete with a
* [SecureSocket] that is connected and ready for subscription.
*
* If [sendClientCertificate] is set to true, the socket will send a client
* certificate if one is requested by the server.
*
* If [certificateName] is the nickname of a certificate in the certificate
* database, that certificate will be sent.
*
* If [certificateName] is null, which is the usual use case, an
* appropriate certificate will be searched for in the database and
* sent automatically, based on what the server says it will accept.
*
* [onBadCertificate] is an optional handler for unverifiable certificates.
* The handler receives the [X509Certificate], and can inspect it and
* decide (or let the user decide) whether to accept
@ -37,14 +27,13 @@ abstract class SecureSocket implements Socket {
static Future<SecureSocket> connect(
host,
int port,
{bool sendClientCertificate: false,
String certificateName,
{SecurityContext context,
bool onBadCertificate(X509Certificate certificate),
bool sendClientCertificate,
List<String> supportedProtocols}) {
return RawSecureSocket.connect(host,
port,
sendClientCertificate: sendClientCertificate,
certificateName: certificateName,
context: context,
onBadCertificate: onBadCertificate,
supportedProtocols: supportedProtocols)
.then((rawSocket) => new SecureSocket._(rawSocket));
@ -79,8 +68,7 @@ abstract class SecureSocket implements Socket {
static Future<SecureSocket> secure(
Socket socket,
{host,
bool sendClientCertificate: false,
String certificateName,
SecurityContext context,
bool onBadCertificate(X509Certificate certificate)}) {
var completer = new Completer();
(socket as dynamic)._detachRaw()
@ -89,7 +77,7 @@ abstract class SecureSocket implements Socket {
detachedRaw[0],
subscription: detachedRaw[1],
host: host,
sendClientCertificate: sendClientCertificate,
context: context,
onBadCertificate: onBadCertificate);
})
.then((raw) {
@ -121,7 +109,7 @@ abstract class SecureSocket implements Socket {
*/
static Future<SecureSocket> secureServer(
Socket socket,
String certificateName,
SecurityContext context,
{List<int> bufferedData,
bool requestClientCertificate: false,
bool requireClientCertificate: false,
@ -131,7 +119,7 @@ abstract class SecureSocket implements Socket {
.then((detachedRaw) {
return RawSecureSocket.secureServer(
detachedRaw[0],
certificateName,
context,
subscription: detachedRaw[1],
bufferedData: bufferedData,
requestClientCertificate: requestClientCertificate,
@ -168,52 +156,6 @@ abstract class SecureSocket implements Socket {
void renegotiate({bool useSessionCache: true,
bool requestClientCertificate: false,
bool requireClientCertificate: false});
/**
* Initializes the NSS library. If [initialize] is not called, the library
* is automatically initialized as if [initialize] were called with no
* arguments. If [initialize] is called more than once, or called after
* automatic initialization has happened (when a secure connection is made),
* then a TlsException is thrown.
*
* The optional argument [database] is the path to a certificate database
* directory containing root certificates for verifying certificate paths on
* client connections, and server certificates to provide on server
* connections. The argument [password] should be used when creating
* secure server sockets, to allow the private key of the server
* certificate to be fetched. If [useBuiltinRoots] is true (the default),
* then a built-in set of root certificates for trusted certificate
* authorities is merged with the certificates in the database.
* The list of built-in root certificates, and documentation about this
* default database, is available at
* http://www.mozilla.org/projects/security/certs/included/ .
*
* If the [database] argument is omitted, then only the
* builtin root certificates are used. If [useBuiltinRoots] is also false,
* then no certificates are available.
*
* Examples:
* 1) Use only the builtin root certificates:
* SecureSocket.initialize(); or
*
* 2) Use a specified database directory and the builtin roots:
* SecureSocket.initialize(database: 'path/to/my/database',
* password: 'my_password');
*
* 3) Use a specified database directory, without builtin roots:
* SecureSocket.initialize(database: 'path/to/my/database',
* password: 'my_password'.
* useBuiltinRoots: false);
*
* The database should be an NSS certificate database directory
* containing a cert9.db file, not a cert8.db file. This version of
* the database can be created using the NSS certutil tool with "sql:" in
* front of the absolute path of the database directory, or setting the
* environment variable [[NSS_DEFAULT_DB_TYPE]] to "sql".
*/
external static void initialize({String database,
String password,
bool useBuiltinRoots: true});
}
@ -224,7 +166,7 @@ abstract class SecureSocket implements Socket {
* RawSecureServerSocket, also returns RawSecureSocket objects representing
* the server end of a secure connection.
* The certificate provided by the server is checked
* using the certificate database provided in SecureSocket.initialize, and/or
* using the trusted certificates set in the SecurityContext object and/or
* the default built-in root certificates.
*/
abstract class RawSecureSocket implements RawSocket {
@ -233,8 +175,9 @@ abstract class RawSecureSocket implements RawSocket {
* host on the given port. The returned Future is completed with the
* RawSecureSocket when it is connected and ready for subscription.
*
* The certificate provided by the server is checked using the certificate
* database provided in [SecureSocket.initialize], and/or the default built-in
* The certificate provided by the server is checked
* using the trusted certificates set in the SecurityContext object and/or
* the default built-in
* root certificates. If [sendClientCertificate] is
* set to true, the socket will send a client certificate if one is
* requested by the server. If [certificateName] is the nickname of
@ -252,24 +195,20 @@ abstract class RawSecureSocket implements RawSocket {
static Future<RawSecureSocket> connect(
host,
int port,
{bool sendClientCertificate: false,
String certificateName,
{SecurityContext context,
bool onBadCertificate(X509Certificate certificate),
List<String> supportedProtocols}) {
_RawSecureSocket._verifyFields(
host,
port,
certificateName,
false,
false,
false,
sendClientCertificate,
onBadCertificate);
return RawSocket.connect(host, port)
.then((socket) {
return secure(socket,
sendClientCertificate: sendClientCertificate,
certificateName: certificateName,
context: context,
onBadCertificate: onBadCertificate,
supportedProtocols: supportedProtocols);
});
@ -307,8 +246,7 @@ abstract class RawSecureSocket implements RawSocket {
RawSocket socket,
{StreamSubscription subscription,
host,
bool sendClientCertificate: false,
String certificateName,
SecurityContext context,
bool onBadCertificate(X509Certificate certificate),
List<String> supportedProtocols}) {
socket.readEventsEnabled = false;
@ -316,11 +254,10 @@ abstract class RawSecureSocket implements RawSocket {
return _RawSecureSocket.connect(
host != null ? host : socket.address.host,
socket.port,
certificateName,
is_server: false,
socket: socket,
subscription: subscription,
sendClientCertificate: sendClientCertificate,
context: context,
onBadCertificate: onBadCertificate,
supportedProtocols: supportedProtocols);
}
@ -350,7 +287,7 @@ abstract class RawSecureSocket implements RawSocket {
*/
static Future<RawSecureSocket> secureServer(
RawSocket socket,
String certificateName,
SecurityContext context,
{StreamSubscription subscription,
List<int> bufferedData,
bool requestClientCertificate: false,
@ -361,7 +298,7 @@ abstract class RawSecureSocket implements RawSocket {
return _RawSecureSocket.connect(
socket.address,
socket.remotePort,
certificateName,
context: context,
is_server: true,
socket: socket,
subscription: subscription,
@ -402,15 +339,13 @@ abstract class RawSecureSocket implements RawSocket {
* X509Certificate represents an SSL certificate, with accessors to
* get the fields of the certificate.
*/
class X509Certificate {
X509Certificate(this.subject,
this.issuer,
this.startValidity,
this.endValidity);
final String subject;
final String issuer;
final DateTime startValidity;
final DateTime endValidity;
abstract class X509Certificate {
external factory X509Certificate._();
String get subject;
String get issuer;
DateTime get startValidity;
DateTime get endValidity;
}
@ -456,10 +391,9 @@ class _RawSecureSocket extends Stream<RawSocketEvent>
int _bufferedDataIndex = 0;
final InternetAddress address;
final bool is_server;
final String certificateName;
SecurityContext context;
final bool requestClientCertificate;
final bool requireClientCertificate;
final bool sendClientCertificate;
final Function onBadCertificate;
var _status = HANDSHAKE;
@ -484,8 +418,8 @@ class _RawSecureSocket extends Stream<RawSocketEvent>
static Future<_RawSecureSocket> connect(
host,
int requestedPort,
String certificateName,
{bool is_server,
SecurityContext context,
RawSocket socket,
StreamSubscription subscription,
List<int> bufferedData,
@ -494,22 +428,21 @@ class _RawSecureSocket extends Stream<RawSocketEvent>
bool sendClientCertificate: false,
bool onBadCertificate(X509Certificate certificate),
List<String> supportedProtocols}) {
_verifyFields(host, requestedPort, certificateName, is_server,
_verifyFields(host, requestedPort, is_server,
requestClientCertificate, requireClientCertificate,
sendClientCertificate, onBadCertificate);
onBadCertificate);
if (host is InternetAddress) host = host.host;
var address = socket.address;
if (host != null) address = address._cloneWithNewHost(host);
return new _RawSecureSocket(address,
requestedPort,
certificateName,
is_server,
context,
socket,
subscription,
bufferedData,
requestClientCertificate,
requireClientCertificate,
sendClientCertificate,
onBadCertificate,
supportedProtocols)
._handshakeComplete.future;
@ -518,16 +451,18 @@ class _RawSecureSocket extends Stream<RawSocketEvent>
_RawSecureSocket(
this.address,
int requestedPort,
this.certificateName,
this.is_server,
this.context,
RawSocket this._socket,
this._socketSubscription,
this._bufferedData,
this.requestClientCertificate,
this.requireClientCertificate,
this.sendClientCertificate,
this.onBadCertificate(X509Certificate certificate),
List<String> supportedProtocols) {
if (context == null) {
context = SecurityContext.defaultContext;
}
_controller = new StreamController<RawSocketEvent>(
sync: true,
onListen: _onSubscriptionStateChange,
@ -570,144 +505,24 @@ class _RawSecureSocket extends Stream<RawSocketEvent>
..onDone(_doneHandler);
}
try {
var encodedProtocols =
SecurityContext._protocolsToLengthEncoding(supportedProtocols);
_secureFilter.connect(address.host,
(address as dynamic)._in_addr,
port,
context,
is_server,
certificateName,
requestClientCertificate ||
requireClientCertificate,
requireClientCertificate,
sendClientCertificate,
_protocolsToLengthEncoding(supportedProtocols));
// TODO(whesse): Remove sendClientCertificate
// argument, or add it to API.
false, // sendClientCertificate,
encodedProtocols);
_secureHandshake();
} catch (e, s) {
_reportError(e, s);
}
}
/// Encodes a set of supported protocols for ALPN/NPN usage.
///
/// The `protocols` list is expected to contain protocols in descending order
/// of preference.
///
/// See RFC 7301 (https://tools.ietf.org/html/rfc7301) for the encoding of
/// `List<String> protocols`:
/// opaque ProtocolName<1..2^8-1>;
///
/// struct {
/// ProtocolName protocol_name_list<2..2^16-1>
/// } ProtocolNameList;
///
/// The encoding of the opaque `ProtocolName<lower..upper>` vector is
/// described in RFC 2246: 4.3 Vectors.
///
/// Note: Even though this encoding scheme would allow a total
/// `ProtocolNameList` length of 65535, this limit cannot be reached. Testing
/// showed that more than ~ 65480 bytes will fail to negogiate a protocol.
/// We will be conservative and support only messages up to (1<<15) -1 bytes.
///
/// Our NSS implementation will support ALPN and NPN transparently. The
/// default protocol will be the first in the encoded Uint8List.
///
/// NOTE: The NSS library will treat the first protocol as the fallback
/// protocol. The remaining ones are sorted in (decreasing) priority order.
/// We therefore put the protocol least desired to the front, to make it the
/// default.
Uint8List _protocolsToLengthEncoding(List<String> protocols) {
if (protocols == null || protocols.length == 0) {
return new Uint8List(0);
}
int protocolsLength = protocols.length;
// Calculate the number of bytes we will need if it is ASCII.
int expectedLength = protocolsLength;
for (int i = 0; i < protocolsLength; i++) {
int length = protocols[i].length;
if (length > 0 && length <= 255) {
expectedLength += length;
} else {
throw new ArgumentError(
'Length of protocol must be between 1 and 255 (was: $length).');
}
}
if (expectedLength >= (1 << 15)) {
throw new ArgumentError(
'The maximum message length supported is 2^15-1.');
}
// Try encoding the `List<String> protocols` array using fast ASCII path.
var bytes = new Uint8List(expectedLength);
int bytesOffset = 0;
for (int i = 0; i < protocolsLength; i++) {
// The last protocol will be encoded as the first/default one in the list.
// (i.e. rotate `protocols` by 1 to the right).
int index = i;
if (index == 0) index = protocols.length;
String proto = protocols[index - 1];
// Add length byte.
bytes[bytesOffset++] = proto.length;
int bits = 0;
// Add protocol bytes.
for (int j = 0; j < proto.length; j++) {
var char = proto.codeUnitAt(j);
bits |= char;
bytes[bytesOffset++] = char & 0xff;
}
// Go slow case if we have encountered anything non-ascii.
if (bits > 0x7f) {
return _protocolsToLengthEncodingNonAsciiBailout(protocols);
}
}
return bytes;
}
Uint8List _protocolsToLengthEncodingNonAsciiBailout(List<String> protocols) {
void addProtocol(List<int> outBytes, String protocol) {
var protocolBytes = UTF8.encode(protocol);
var len = protocolBytes.length;
if (len > 255) {
throw new ArgumentError(
'Length of protocol must be between 1 and 255 (was: $len)');
}
// Add length byte.
outBytes.add(len);
// Add protocol bytes.
outBytes.addAll(protocolBytes);
}
List<int> bytes = [];
addProtocol(bytes, protocols.last);
for (var i = 0; i < protocols.length -1; i++) {
addProtocol(bytes, protocols[i]);
}
if (bytes.length >= (1 << 15)) {
throw new ArgumentError(
'The maximum message length supported is 2^15-1.');
}
return new Uint8List.fromList(bytes);
}
void _addProtocolBytes(List<int> outBytes, String protocol) {
var protocolBytes = UTF8.encode(protocol);
var len = protocolBytes.length;
if (len > 255) {
throw new ArgumentError(
'Cannot support protocols with more than 255 characters');
}
outBytes.add(len);
outBytes.addAll(protocolBytes);
}
StreamSubscription listen(void onData(RawSocketEvent data),
{Function onError,
void onDone(),
@ -721,11 +536,9 @@ class _RawSecureSocket extends Stream<RawSocketEvent>
static void _verifyFields(host,
int requestedPort,
String certificateName,
bool is_server,
bool requestClientCertificate,
bool requireClientCertificate,
bool sendClientCertificate,
Function onBadCertificate) {
if (host is! String && host is! InternetAddress) {
throw new ArgumentError("host is not a String or an InternetAddress");
@ -736,21 +549,12 @@ class _RawSecureSocket extends Stream<RawSocketEvent>
if (requestedPort < 0 || requestedPort > 65535) {
throw new ArgumentError("requestedPort is not in the range 0..65535");
}
if (certificateName != null && certificateName is! String) {
throw new ArgumentError("certificateName is not null or a String");
}
if (certificateName == null && is_server) {
throw new ArgumentError("certificateName is null on a server");
}
if (requestClientCertificate is! bool) {
throw new ArgumentError("requestClientCertificate is not a bool");
}
if (requireClientCertificate is! bool) {
throw new ArgumentError("requireClientCertificate is not a bool");
}
if (sendClientCertificate is! bool) {
throw new ArgumentError("sendClientCertificate is not a bool");
}
if (onBadCertificate != null && onBadCertificate is! Function) {
throw new ArgumentError("onBadCertificate is not null or a Function");
}
@ -891,7 +695,7 @@ class _RawSecureSocket extends Stream<RawSocketEvent>
if (onBadCertificate == null) return false;
var result = onBadCertificate(certificate);
if (result is bool) return result;
throw new ArgumentError(
throw new HandshakeException(
"onBadCertificate callback returned non-boolean $result");
}
@ -1360,10 +1164,8 @@ abstract class _SecureFilter {
external factory _SecureFilter();
void connect(String hostName,
Uint8List addr,
int port,
SecurityContext context,
bool is_server,
String certificateName,
bool requestClientCertificate,
bool requireClientCertificate,
bool sendClientCertificate,

View File

@ -0,0 +1,184 @@
// Copyright (c) 2015, the Dart project authors. Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
part of dart.io;
/**
* The object containing the certificates to trust when making
* a secure client connection, and the certificate chain and
* private key to serve from a secure server.
*
* The [SecureSocket] and [SecureServer] classes take a SecurityContext
* as an argument to their connect and bind methods.
*
* Certificates and keys can be added to a SecurityContext from PEM files
* on the disk. A PEM file contains one or more base-64 encoded DER-serialized
* ASN1 objects, surrounded with delimiter strings like
* "-----BEGIN CERTIFICATE -----" and "-----END CERTIFICATE-----".
* Distinguished encoding rules (DER) is a canonical binary serialization
* of ASN1 objects into an octet string.
*/
abstract class SecurityContext {
external factory SecurityContext();
external static SecurityContext get defaultContext;
/**
* Sets the private key for a server certificate or client certificate.
* A secure connection using this SecurityContext will use this key with
* the server or client certificate to sign and decrypt messages.
* [keyFile] is a PEM file containing an encrypted
* private key, encrypted with [password]. An unencrypted file can be
* used, but this is not usual.
*/
void usePrivateKey(String keyFile, {String password});
/**
* Sets the set of trusted X509 certificates used by [SecureSocket]
* client connections, when connecting to a secure server.
*
* There are two ways to set a set of trusted certificates, with a single
* PEM file, or with a directory containing individual PEM files for
* certificates.
*
* [file] is an optional PEM file containing X509 certificates, usually
* root certificates from certificate authorities.
*
* [directory] is an optional directory containing PEM files. The directory
* must also have filesystem links added, which link extra filenames based
* on the hash of a certificate's distinguished name (DN) to the file
* containing that certificate. OpenSSL contains a tool called c_rehash
* to create these links in a directory.
*/
void setTrustedCertificates({String file, String directory});
/**
* Sets the chain of X509 certificates served by [SecureServer]
* when making secure connections, including the server certificate.
* [file] is an PEM file containing X509 certificates, starting with
* the root authority and intermediate authorities forming the signed
* chain to the server certificate, and ending with the server certificate.
* The private key for the server certificate is set by [usePrivateKey].
*/
void useCertificateChain(String file);
/**
* Sets the list of authority names that a [SecureServer] will advertise
* as accepted, when requesting a client certificate from a connecting
* client. [file] is a PEM file containing the accepted signing authority
* certificates - the authority names are extracted from the certificates.
*/
void setClientAuthorities(String file);
/**
* Sets the list of application-level protocols supported by a client
* connection or server connection. The ALPN (application level protocol
* negotiation) extension to TLS allows a client to send a list of
* protocols in the TLS client hello message, and the server to pick
* one and send the selected one back in its server hello message.
*
* Separate lists of protocols can be sent for client connections and
* for server connections, using the same SecurityContext. The [isServer]
* boolean argument specifies whether to set the list for server connections
* or client connections.
*/
void setAlpnProtocols(List<String> protocols, bool isServer);
/// Encodes a set of supported protocols for ALPN/NPN usage.
///
/// The `protocols` list is expected to contain protocols in descending order
/// of preference.
///
/// See RFC 7301 (https://tools.ietf.org/html/rfc7301) for the encoding of
/// `List<String> protocols`:
/// opaque ProtocolName<1..2^8-1>;
///
/// struct {
/// ProtocolName protocol_name_list<2..2^16-1>
/// } ProtocolNameList;
///
/// The encoding of the opaque `ProtocolName<lower..upper>` vector is
/// described in RFC 2246: 4.3 Vectors.
///
/// Note: Even though this encoding scheme would allow a total
/// `ProtocolNameList` length of 65535, this limit cannot be reached. Testing
/// showed that more than ~ 2^14 bytes will fail to negotiate a protocol.
/// We will be conservative and support only messages up to (1<<13)-1 bytes.
static Uint8List _protocolsToLengthEncoding(List<String> protocols) {
if (protocols == null || protocols.length == 0) {
return new Uint8List(0);
}
int protocolsLength = protocols.length;
// Calculate the number of bytes we will need if it is ASCII.
int expectedLength = protocolsLength;
for (int i = 0; i < protocolsLength; i++) {
int length = protocols[i].length;
if (length > 0 && length <= 255) {
expectedLength += length;
} else {
throw new ArgumentError(
'Length of protocol must be between 1 and 255 (was: $length).');
}
}
if (expectedLength >= (1 << 13)) {
throw new ArgumentError(
'The maximum message length supported is 2^13-1.');
}
// Try encoding the `List<String> protocols` array using fast ASCII path.
var bytes = new Uint8List(expectedLength);
int bytesOffset = 0;
for (int i = 0; i < protocolsLength; i++) {
String proto = protocols[i];
// Add length byte.
bytes[bytesOffset++] = proto.length;
int bits = 0;
// Add protocol bytes.
for (int j = 0; j < proto.length; j++) {
var char = proto.codeUnitAt(j);
bits |= char;
bytes[bytesOffset++] = char & 0xff;
}
// Go slow case if we have encountered anything non-ascii.
if (bits > 0x7f) {
return _protocolsToLengthEncodingNonAsciiBailout(protocols);
}
}
return bytes;
}
static Uint8List _protocolsToLengthEncodingNonAsciiBailout(
List<String> protocols) {
void addProtocol(List<int> outBytes, String protocol) {
var protocolBytes = UTF8.encode(protocol);
var len = protocolBytes.length;
if (len > 255) {
throw new ArgumentError(
'Length of protocol must be between 1 and 255 (was: $len)');
}
// Add length byte.
outBytes.add(len);
// Add protocol bytes.
outBytes.addAll(protocolBytes);
}
List<int> bytes = [];
for (var i = 0; i < protocols.length; i++) {
addProtocol(bytes, protocols[i]);
}
if (bytes.length >= (1 << 13)) {
throw new ArgumentError(
'The maximum message length supported is 2^13-1.');
}
return new Uint8List.fromList(bytes);
}
}

View File

@ -41,6 +41,12 @@ var blacklist = [
'dart.io.SystemEncoding.decode', // Windows only
'dart.io.SystemEncoding.encode', // Windows only
// These construct an object with an uninitialized native field.
// TODO(23869): We could make this safer, but making the failure non-fatal
// would we worthless aside from this test.
'dart.io.X509Certificate.X509Certificate._',
'dart.io._X509Impl._X509Impl',
// Don't call private methods in dart.async as they may circumvent the zoned
// error handling below.
new RegExp(r"^dart\.async\._.*$"),

View File

@ -0,0 +1,31 @@
This directory, tests/standalone/io/certificates, contains the
X509 TLS certificates and private keys needed to run tests of Dart's
secure networking code. The SecureSocket and SecureServer classes
are tested by making TLS (formerly called SSL) connections, secured
by certificates created by the create_test_certificates script in
the parent directory, and copied into this directory.
server_chain.pem:
Contains the chain of certificates, from the self-signed
test certificate authority, through the intermediate CA, to the server
certificate, used on the server side of a test connection.
server_key.pem:
Contains the private key for the server certificate
trusted_certs.pem:
Contains the self-signed certificate of the test certificate authority.
This certificate is set as "trusted" by the client side of the connection
in its SecurityContext object, so that a verified TLS connection to the
server can be made.
untrusted_server_chain.pem:
Contains a chain of certificates, from a different self-signed
test certificate authority, through an intermediate CA, to a server
certificate, used on the server side of a test connection that is intended
to fail because the client does not accept this certificate authority
untrusted_server_key.pem:
Contains the private key for the untrusted server certificate
in untrusted_server_chain.pem

View File

@ -0,0 +1,57 @@
-----BEGIN CERTIFICATE-----
MIIDKTCCAhGgAwIBAgIJAOWmjTS+OnTEMA0GCSqGSIb3DQEBCwUAMBcxFTATBgNV
BAMMDGludGVybWVkaWF0ZTAeFw0xNTA1MTgwOTAwNDBaFw0yMzA4MDQwOTAwNDBa
MBQxEjAQBgNVBAMMCWxvY2FsaG9zdDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCC
AQoCggEBALlcwQJuzd+xH8QFgfJSn5tRlvhkldSX98cE7NiA602NBbnAVyUrkRXq
Ni75lgt0kwjYfA9z674m8WSVbgpLPintPCla9CYky1TH0keIs8Rz6cGWHryWEHiu
EDuljQynu2b3sAFuHu9nfWurbJwZnFakBKpdQ9m4EyOZCHC/jHYY7HacKSXg1Cki
we2ca0BWDrcqy8kLy0dZ5oC6IZG8O8drAK8f3f44CRYw59D3sOKBrKXaabpvyEcb
N7Wk2HDBVwHpUJo1reVwtbM8dhqQayYSD8oXnGpP3RQNu/e2rzlXRyq/BfcDY1JI
7TbC4t/7/N4EcPSpGsTcSOC9A7FpzvECAwEAAaN7MHkwCQYDVR0TBAIwADAsBglg
hkgBhvhCAQ0EHxYdT3BlblNTTCBHZW5lcmF0ZWQgQ2VydGlmaWNhdGUwHQYDVR0O
BBYEFCnwiEMMFZh7NhCr+qA8K0w4Q+AOMB8GA1UdIwQYMBaAFB0h1Evsaw2vfrmS
YuoCTmC4EE6ZMA0GCSqGSIb3DQEBCwUAA4IBAQAcFmHMaXRxyoNaeOowQ6iQWoZd
AUbvG7SHr7I6Pi2aqdqofsKWts7Ytm5WsS0M2nN+sW504houu0iCPeJJX8RQw2q4
CCcNOs9IXk+2uMzlpocHpv+yYoUiD5DxgWh7eghQMLyMpf8FX3Gy4VazeuXznHOM
4gE4L417xkDzYOzqVTp0FTyAPUv6G2euhNCD6TMru9REcRhYul+K9kocjA5tt2KG
MH6y28LXbLyq4YJUxSUU9gY/xlnbbZS48KDqEcdYC9zjW9nQ0qS+XQuQuFIcwjJ5
V4kAUYxDu6FoTpyQjgsrmBbZlKNxH7Nj4NDlcdJhp/zeSKHqWa5hSWjjKIxp
-----END CERTIFICATE-----
-----BEGIN CERTIFICATE-----
MIIDAjCCAeqgAwIBAgIJAOWmjTS+OnTDMA0GCSqGSIb3DQEBCwUAMBgxFjAUBgNV
BAMMDXJvb3RhdXRob3JpdHkwHhcNMTUwNTE4MDkwMDQwWhcNMjMwODA0MDkwMDQw
WjAXMRUwEwYDVQQDDAxpbnRlcm1lZGlhdGUwggEiMA0GCSqGSIb3DQEBAQUAA4IB
DwAwggEKAoIBAQDSrAO1CoPvUllgLOzDm5nG0skDF7vh1DUgAIDVGz0ecD0JFbQx
EF79pju/6MbtpTW2FYvRp11t/G7rGtX923ybOHY/1MNFQrdIvPlO1VV7IGKjoMwP
DNeb0fIGjHoE9QxaDxR8NX8xQbItpsw+TUtRfc9SLkR+jaYJfVRoM21BOncZbSHE
YKiZlEbpecB/+EtwVpgvl+8mPD5U07Fi4fp/lza3WXInXQPyiTVllIEJCt4PKmlu
MocNaJOW38bysL7i0PzDpVZtOxLHOTaW68yF3FckIHNCaA7k1ABEEEegjFMmIao7
B9w7A0jvr4jZVvNmui5Djjn+oJxwEVVgyf8LAgMBAAGjUDBOMB0GA1UdDgQWBBQd
IdRL7GsNr365kmLqAk5guBBOmTAfBgNVHSMEGDAWgBRk81s9d0ZbiZhh44KckwPb
oTc0XzAMBgNVHRMEBTADAQH/MA0GCSqGSIb3DQEBCwUAA4IBAQBZQTK0plfdB5PC
cC5icut4EmrByJa1RbU7ayuEE70e7hla6KVmVjVdCBGltI4jBYwfhKbRItHiAJ/8
x+XZKBG8DLPFuDb7lAa1ObhAYF7YThUFPQYaBhfzKcWrdmWDBFpvNv6E0Mm364dZ
e7Yxmbe5S4agkYPoxEzgEYmcUk9jbjdR6eTbs8laG169ljrECXfEU9RiAcqz5iSX
NLSewqB47hn3B9qgKcQn+PsgO2j7M+rfklhNgeGJeWmy7j6clSOuCsIjWHU0RLQ4
0W3SB/rpEAJ7fgQbYUPTIUNALSOWi/o1tDX2mXPRjBoxqAv7I+vYk1lZPmSzkyRh
FKvRDxsW
-----END CERTIFICATE-----
-----BEGIN CERTIFICATE-----
MIIDAzCCAeugAwIBAgIJAJ0MomS4Ck+8MA0GCSqGSIb3DQEBCwUAMBgxFjAUBgNV
BAMMDXJvb3RhdXRob3JpdHkwHhcNMTUwNTE4MDkwMDQwWhcNMjMwODA0MDkwMDQw
WjAYMRYwFAYDVQQDDA1yb290YXV0aG9yaXR5MIIBIjANBgkqhkiG9w0BAQEFAAOC
AQ8AMIIBCgKCAQEAts1ijtBV92S2cOvpUMOSTp9c6A34nIGr0T5Nhz6XiqRVT+gv
dQgmkdKJQjbvR60y6jzltYFsI2MpGVXY8h/oAL81D/k7PDB2aREgyBfTPAhBHyGw
siR+2xYt5b/Zs99q5RdRqQNzNpLPJriIKvUsRyQWy1UiG2s7pRXQeA8qB0XtJdCj
kFIi+G2bDsaffspGeDOCqt7t+yqvRXfSES0c/l7DIHaiMbbp4//ZNML3RNgAjPz2
hCezZ+wOYajOIyoSPK8IgICrhYFYxvgWxwbLDBEfC5B3jOQsySe10GoRAKZz1gBV
DmgReu81tYJmdgkc9zknnQtIFdA0ex+GvZlfWQIDAQABo1AwTjAdBgNVHQ4EFgQU
ZPNbPXdGW4mYYeOCnJMD26E3NF8wHwYDVR0jBBgwFoAUZPNbPXdGW4mYYeOCnJMD
26E3NF8wDAYDVR0TBAUwAwEB/zANBgkqhkiG9w0BAQsFAAOCAQEATzkZ97K777uZ
lQcduNX3ey4IbCiEzFA2zO5Blj+ilfIwNbZXNOgm/lqNvVGDYs6J1apJJe30vL3X
J+t2zsZWzzQzb9uIU37zYemt6m0fHrSrx/iy5lGNqt3HMfqEcOqSCOIK3PCTMz2/
uyGe1iw33PVeWsm1JUybQ9IrU/huJjbgOHU4wab+8SJCM49ipArp68Fr6j4lcEaE
4rfRg1ZsvxiOyUB3qPn6wyL/JB8kOJ+QCBe498376eaem8AEFk0kQRh6hDaWtq/k
t6IIXQLjx+EBDVP/veK0UnVhKRP8YTOoV8ZiG1NcdlJmX/Uk7iAfevP7CkBfSN8W
r6AL284qtw==
-----END CERTIFICATE-----

View File

@ -0,0 +1,29 @@
-----BEGIN ENCRYPTED PRIVATE KEY-----
MIIE5DAcBgoqhkiG9w0BDAEBMA4ECL7L6rj6uEHGAgIIAASCBMLbucyfqAkgCbhP
xNSHYllPMAv/dsIjtnsBwepCXPGkCBCuOAw/2FaCHjN9hBqL5V7fkrKeaemhm2YE
ycPtlHJYPDf3kEkyMjdZ9rIY6kePGfQizs2uJPcXj4YPyQ4HsfVXpOicKfQrouf5
Mze9bGzeMN065q3iP4dYUMwHAyZYteXCsanQNHlqvsWli0W+H8St8fdsXefZhnv1
qVatKWdNdWQ9t5MuljgNU2Vv56sHKEYXI0yLxk2QUMk8KlJfnmt8foYUsnPUXHmc
gIjLKwwVkpdololnEHSNu0cEOUPowjgJru+uMpn7vdNl7TPEQ9jbEgdNg4JwoYzU
0nao8WzjaSp7kzvZz0VFwKnk5AjstGvvuAWckADdq23QElbn/mF7AG1m/TBpYxzF
gTt37UdndS/AcvVznWVVrRP5iTSIawdIwvqI4s7rqsoE0GCcak+RhchgAz2gWKkS
oODUo0JL6pPVbJ3l4ebbaO6c99nDVc8dViPtc1EkStJEJ2O4kI4xgLSCr4Y9ahKn
oAaoSkX7Xxq3aQm+BzqSpLjdGL8atsqR/YVOIHYIl3gThvP0NfZGx1xHyvO5mCdZ
kHxSA7tKWxauZ3eQ2clbnzeRsl4El0WMHy/5K1ovene4v7sunmoXVtghBC8hK6eh
zMO9orex2PNQ/VQC7HCvtytunOVx1lkSBoNo7hR70igg6rW9H7UyoAoBOwMpT1xa
J6V62nqruTKOqFNfur7aHJGpHGtDb5/ickHeYCyPTvmGp67u4wChzKReeg02oECe
d1E5FKAcIa8s9TVOB6Z+HvTRNQZu2PsI6TJnjQRowvY9DAHiWTlJZBBY/pko3hxX
TsIeybpvRdEHpDWv86/iqtw1hv9CUxS/8ZTWUgBo+osShHW79FeDASr9FC4/Zn76
ZDERTgV4YWlW/klVWcG2lFo7jix+OPXAB+ZQavLhlN1xdWBcIz1AUWjAM4hdPylW
HCX4PB9CQIPl2E7F+Y2p6nMcMWSJVBi5UIH7E9LfaBguXSzMmTk2Fw5p1aOQ6wfN
goVAMVwi8ppAVs741PfHdZ295xMmK/1LCxz5DeAdD/tsA/SYfT753GotioDuC7im
EyJ5JyvTr5I6RFFBuqt3NlUb3Hp16wP3B2x9DZiB6jxr0l341/NHgsyeBXkuIy9j
ON2mvpBPCJhS8kgWo3G0UyyKnx64tcgpGuSvZhGwPz843B6AbYyE6pMRfSWRMkMS
YZYa+VNKhR4ixdj07ocFZEWLVjCH7kxkE8JZXKt8jKYmkWd0lS1QVjgaKlO6lRa3
q6SPJkhW6pvqobvcqVNXwi1XuzpZeEbuh0B7OTekFTTxx5g9XeDl56M8SVQ1KEhT
Q1t7H2Nba18WCB7cf+6PN0F0K0Jz1Kq7ZWaqEI/grX1m4RQuvNF5807sB/QKMO/Z
Gz3NXvHg5xTJRd/567lxPGkor0cE7qD1EZfmJ2HrBYXQ91bhgA7LToBuMZo6ZRXH
QfsanjbP4FPLMiGdQigLjj3A35L/f4sQOOVac/sRaFnm7pzcxsMvyVU/YtvGcjYE
xaOOVnamg661Wo0wksXoDjeSz/JIyyKO3Gwp1FSm2wGLjjy/Ehmqcqy8rvHuf07w
AUukhVtTNn4=
-----END ENCRYPTED PRIVATE KEY-----

View File

@ -0,0 +1,19 @@
-----BEGIN CERTIFICATE-----
MIIDAzCCAeugAwIBAgIJAJ0MomS4Ck+8MA0GCSqGSIb3DQEBCwUAMBgxFjAUBgNV
BAMMDXJvb3RhdXRob3JpdHkwHhcNMTUwNTE4MDkwMDQwWhcNMjMwODA0MDkwMDQw
WjAYMRYwFAYDVQQDDA1yb290YXV0aG9yaXR5MIIBIjANBgkqhkiG9w0BAQEFAAOC
AQ8AMIIBCgKCAQEAts1ijtBV92S2cOvpUMOSTp9c6A34nIGr0T5Nhz6XiqRVT+gv
dQgmkdKJQjbvR60y6jzltYFsI2MpGVXY8h/oAL81D/k7PDB2aREgyBfTPAhBHyGw
siR+2xYt5b/Zs99q5RdRqQNzNpLPJriIKvUsRyQWy1UiG2s7pRXQeA8qB0XtJdCj
kFIi+G2bDsaffspGeDOCqt7t+yqvRXfSES0c/l7DIHaiMbbp4//ZNML3RNgAjPz2
hCezZ+wOYajOIyoSPK8IgICrhYFYxvgWxwbLDBEfC5B3jOQsySe10GoRAKZz1gBV
DmgReu81tYJmdgkc9zknnQtIFdA0ex+GvZlfWQIDAQABo1AwTjAdBgNVHQ4EFgQU
ZPNbPXdGW4mYYeOCnJMD26E3NF8wHwYDVR0jBBgwFoAUZPNbPXdGW4mYYeOCnJMD
26E3NF8wDAYDVR0TBAUwAwEB/zANBgkqhkiG9w0BAQsFAAOCAQEATzkZ97K777uZ
lQcduNX3ey4IbCiEzFA2zO5Blj+ilfIwNbZXNOgm/lqNvVGDYs6J1apJJe30vL3X
J+t2zsZWzzQzb9uIU37zYemt6m0fHrSrx/iy5lGNqt3HMfqEcOqSCOIK3PCTMz2/
uyGe1iw33PVeWsm1JUybQ9IrU/huJjbgOHU4wab+8SJCM49ipArp68Fr6j4lcEaE
4rfRg1ZsvxiOyUB3qPn6wyL/JB8kOJ+QCBe498376eaem8AEFk0kQRh6hDaWtq/k
t6IIXQLjx+EBDVP/veK0UnVhKRP8YTOoV8ZiG1NcdlJmX/Uk7iAfevP7CkBfSN8W
r6AL284qtw==
-----END CERTIFICATE-----

View File

@ -0,0 +1,57 @@
-----BEGIN CERTIFICATE-----
MIIDKTCCAhGgAwIBAgIJAOLkVK1iIzcgMA0GCSqGSIb3DQEBCwUAMBcxFTATBgNV
BAMMDGludGVybWVkaWF0ZTAeFw0xNTA1MjgxNTAyMTlaFw0yMzA4MTQxNTAyMTla
MBQxEjAQBgNVBAMMCWxvY2FsaG9zdDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCC
AQoCggEBAJTI9uVvjQ5jsHB+UcqhXOKXmt8QlK3gOZKYs9lCFoQYWVug3daDCYp6
p1N7/lM+V0sDhYfALBjT9aetviTck8ZJ5rCJ1xzyY16/LnvTI9wjBeizyar5K57A
vRwX+PB4OQi4nKszWXB++jYu7AYJsIwQwkNAk5kkpaVRlWqYkDm6JqtD6hAPxQV4
0rrqQAXBY+SP0C8buhVNDmnkshmJnHnb/yodNmwdK0CkSN9TbVZi3UpsDRL1Tbo/
i7fRrfVK5aTjdjT7yx/5Wh2jQ4nBdm7l5BFc2owHk0FGB9h5GMgs19RzHf+O+JCc
SabuVSehtagIouiwHOJ5iFtiq6enF58CAwEAAaN7MHkwCQYDVR0TBAIwADAsBglg
hkgBhvhCAQ0EHxYdT3BlblNTTCBHZW5lcmF0ZWQgQ2VydGlmaWNhdGUwHQYDVR0O
BBYEFKpMad7rFfjy9iTqyCBJSWORnxqoMB8GA1UdIwQYMBaAFDqe3VrQlMZ2ABqb
w16kdoDbumRuMA0GCSqGSIb3DQEBCwUAA4IBAQC9rRoBEcCZBVCBVZdckq0cWVYB
IoMnpGk1ODv5Yp2b36LR3wwr2g+2u61s767L0+2ZGbGACkzWi3rJFSWIiH2j5zmi
e+TvuOXFbw0r2PtiYDaoWIExzkC3rxnCSlUdbRPw1LI8bEd3+PYeZcEW0zs+xaId
lctsWe8QC7EW3trLUFc8ASjED4uO83+2toqljkrD4SDnVz8t7O6bNrKrEDkNrxDW
NHrbSP8m666U/A4MpH55BArfHNlUbzOZ6/jOkvcqhbL1pccJ2U1Ov3GnQGk7Vg+D
JD1ptD6AHnjA8PCSkDOPibG4w9lRFWaUeAjtuCq1xJ3RFe5aUcUqgcxyF38B
-----END CERTIFICATE-----
-----BEGIN CERTIFICATE-----
MIIDAjCCAeqgAwIBAgIJAOLkVK1iIzcfMA0GCSqGSIb3DQEBCwUAMBgxFjAUBgNV
BAMMDXJvb3RhdXRob3JpdHkwHhcNMTUwNTI4MTUwMjE5WhcNMjMwODE0MTUwMjE5
WjAXMRUwEwYDVQQDDAxpbnRlcm1lZGlhdGUwggEiMA0GCSqGSIb3DQEBAQUAA4IB
DwAwggEKAoIBAQDS0BrhfsYaZcm68pdZ2j+TWXa/Ba5s3sKq9+EFcI5ZSq8/Atn+
V17OgyjUYQDS//8lk0UydvHQmI6lTSAlLbIDfHMQZ1qxKGV75IgLmHO2RCoJ0W2p
V74m6EZ3cMMOAFJ1WO292ee1H3ZynZSJcj5jxzLzJwOzaz9IjVVLpRdvm2xkhuIa
M10aYn3gohGLaq8fe8sQx4ezx6nlqAFK1rZrMKgmPoDaV/Vsin71QywAjOApMp/c
GkQjRzmUQf12NfXuvQU6ZP0M16e6Od0oAUFM+t0OjFUCcfhwRfGsoSesLof3Gc8+
eJ7LbOFxWMvsFwsXkmeDvE6yuihBlPm38Va3AgMBAAGjUDBOMB0GA1UdDgQWBBQ6
nt1a0JTGdgAam8NepHaA27pkbjAfBgNVHSMEGDAWgBSjeMkHbMP4BXJRnx4iJOhN
ir7L+DAMBgNVHRMEBTADAQH/MA0GCSqGSIb3DQEBCwUAA4IBAQAyQYc8ZrQZAlGw
I0AFYaG/T3waQFr48j3evBEO9RT/3E8+rNbW4QKyzovJhBiNwkqJhn+WNW7B43zT
jG3MqH3FTcQfjcXGxFUPh1HntMz7RbXs3Pv5G1f5knk6Hy63vG432kAEUZbrAdKV
yBnR3/VqZd8cX1nzZkhEh9ePz6XTsKctXaHfnenQZJ3YwwNAwlNiNeXB/ykJliyh
8AJxBQdx76TudXB0pl92bK0nsNVczGXg4UZ80GbCHGoYV9ZjQCX/G5ocquMB11Ou
2n9iHTPHMdkahDvWwHggLXrCZK2to4N5zYz33dMhnRiR5hVZKaxuql1j9O2kwLCD
Yb7VgstA
-----END CERTIFICATE-----
-----BEGIN CERTIFICATE-----
MIIDAzCCAeugAwIBAgIJALj/jZ2qE13WMA0GCSqGSIb3DQEBCwUAMBgxFjAUBgNV
BAMMDXJvb3RhdXRob3JpdHkwHhcNMTUwNTI4MTUwMjE5WhcNMjMwODE0MTUwMjE5
WjAYMRYwFAYDVQQDDA1yb290YXV0aG9yaXR5MIIBIjANBgkqhkiG9w0BAQEFAAOC
AQ8AMIIBCgKCAQEAp3u9wYL5IexhJAzuCDI1nL/JFT5itluFcGA2UjKF12hDUG5b
ipvG8Oxi7oOo9Nk32sw5hqNVyCXp35znOZBnnQn6kkLNENRZ0JlprBYZVG+2jTZI
jxSq8kYWMkeP21BmwfgPuorpfM8ClDCHbrOJuHFeP1U/rqj7A2Hw1VjuPD+5VmWK
N8EeZsis1vOKWtrQfwEukCUfu6gScsIFa9Pie7r5YufYYWMUGPktI0r1r0S9iTY2
femCqWIL4jfYKQ8d0ibYE7obM/fhIYUyhSZyCes3ffDpP22/puwkwZMopqIXaB17
At6q4YXv9RjJQm/CXGoMBzddAiQbpStKA3nAxwIDAQABo1AwTjAdBgNVHQ4EFgQU
o3jJB2zD+AVyUZ8eIiToTYq+y/gwHwYDVR0jBBgwFoAUo3jJB2zD+AVyUZ8eIiTo
TYq+y/gwDAYDVR0TBAUwAwEB/zANBgkqhkiG9w0BAQsFAAOCAQEAjOWWBiCBmzfu
pvct3CMMDAgLB+N51SrDeowG++Zyv8mtEzaC2nSD2rwztrHKbRInflH5FclFFFKr
EY7wfL86MZUECpA7QjRpwhaqe7d2uUmi+kOSg3I9AL0KVdM4jOIcNTrzrDjaUpsF
v9U4ounXQyRI9x8H/v8rzMMQmEeq3DyKqOr6y46U6SspDDlLcGGxQz1olmNYsxw5
ftY1/Q58HGDsUEMUC2hOCsKw8XxSguLln0inMXpws+rWOZLETN4+WMxZojYmLqz+
DksVeUKBx1IJx3WLNkj/qk55w/4dJPBfddNJ76KFKxxYwzZ851Y9f6+OndRTGW1n
XJOiJnRvlQ==
-----END CERTIFICATE-----

View File

@ -0,0 +1,29 @@
-----BEGIN ENCRYPTED PRIVATE KEY-----
MIIE5DAcBgoqhkiG9w0BDAEBMA4ECPM4xVvIwo+2AgIIAASCBMJ/88x+fp/JrzbU
TCCt4ic7v+w7nVPOpxtvbQAQ6/kWQcKyjNdeqqktlW/5NvhPOXYWzRZIFkts9BSh
kyTHqxRa8QFn/PcoqKF6rRUCfoKfROQNnoNP/E//Z7dxg9sUPpHxs7tlwuoBr2dv
Cnmh/WiJaeOvIEnFOa/ZwTljWjIEfmUHhVK351c6JyRVPDAPKsg2+hWNfQpdqPIz
ptoDT+gGDY6rMp/eMbpu0g7Dal+q1sC/FQe5hGXWtIz27hHuJxY9V0yOwpW9Q5k9
dg4KOqrJLW8O3ZF0l/oXOG+V5i9rMJWJyq9GR2LdxmdgL3nKibE6DCZXG/cMcY2O
ApdCaUzyREM2Qidcp45rWNkVO+5enVh0tiYQY12vvUnDCq5ysKW3FmEXH+uBgy0l
jh2Wkwlag3wwKis6YeSTQBYO5i+M5vqXXi/yZ5b45Jnjs6rhX5d7scmzaFeLitBz
GQsNTvrQCNDmbcNVex5k10cxv9eAlsepTIlknwnFItqAmo2idf5Mh51hEvwb9jEQ
BRLiQIEgmkba2YSU5Vg1SkAEzAm1FCcbc0U8UF90A/Uv/un0VNDii+PxCp8xskvr
5PmKssF1q1GmuzyWpQ97HKKTP87r/a2OZhxDr876UQnBM6R6mrFF9efyARmc2a7l
fkuBgpP0ExP69Br8KdWctuyCtIJtY/4CnCJZvEa0FTyurxqh+nrce/YBXZxK7f+2
NWqEAIwTdmsIRvm6jAr7m/ySsXFP+wjcFVgJ3JwSHc+NO1/NhSSJFXD4dUH7+Xxw
kUeH7jxrbcFDLA0zXLtVAMuyoX2HTp/AA+COsAXLLtSzifY8RPDloioeqFW2FZ3d
mvsmjoCVyQK7sJ5+ZwlGqnwOtp2iK2VHjk/Y+J4HUBpcYkUjFFlqa8Bkc7w8BCkI
nV+hWEQn3nAJiEXtK+PlJfWz4YKUTyOwCp1xvNOrBByXgG5w5bv9RtqpolyN6rh2
WUcNtt36eMnzj6bBXib9VoOWD2ls0AIIl8EON4KIizI+inY21Lb9f15066UvRm6s
5Rudi9v7iS+FcOG9bP2pg0sCoooLHqSVE2me1tcI3vDjZH8O3sjo4/YO7W0Vbc2+
atxzq9cWGWZvpa7grafdqDhcRNqbpBGsUdq0Tps6pMnymjWWHK7x+m61R6wXafBm
lyT9lyh7y3A9oTtO91QO1VhNY8E0bpF9EkGBIO+VCK7XNvRO7ITZdfsmCgjNQ14u
iimruX0scOggq3xZ2VjPCrZXbWGO6GD1bJVFqBZmXLDq/YHHC0UbM2eQFcTWXKV3
S2+pGmrBHlwPPQmvrLBQr8TMzRX/HOLCpUyuNU6bXrkyXIrBKBCj1XOmNtNUBe6O
PcMQ7BoUf/zsR8XPFbQV+4pidsMNmm9j4g40CBFwAQv2INC385wJIIsjKxewPy+6
cYmyTtQX+1XPACpQA8BLq9qNkvbJTeXAeAcoA21WtlJjREzpqRA6j0j7Em7oHJNe
tH7EsBz+KdiYWk/xFRxHICn7TvLTpf5+Xw1pfZfV7Lxpk6ae2fcOr9MjkGqm5YqZ
VQFdnJ8U+RNC7/yPxDoFqndSI3RsAIXFMvMDOMmToCGwDCt2fFWPgwZeGYj0Qh1c
7shiDBng3TE=
-----END ENCRYPTED PRIVATE KEY-----

View File

@ -35,6 +35,7 @@ part "../../../sdk/lib/io/platform_impl.dart";
part "../../../sdk/lib/io/service_object.dart";
part "../../../sdk/lib/io/secure_socket.dart";
part "../../../sdk/lib/io/secure_server_socket.dart";
part "../../../sdk/lib/io/security_context.dart";
part "../../../sdk/lib/io/socket.dart";
void testParseHttpCookieDate() {

View File

@ -35,6 +35,7 @@ part "../../../sdk/lib/io/platform_impl.dart";
part "../../../sdk/lib/io/service_object.dart";
part "../../../sdk/lib/io/secure_socket.dart";
part "../../../sdk/lib/io/secure_server_socket.dart";
part "../../../sdk/lib/io/security_context.dart";
part "../../../sdk/lib/io/socket.dart";
void testMultiValue() {

View File

@ -35,6 +35,7 @@ part "../../../sdk/lib/io/platform_impl.dart";
part "../../../sdk/lib/io/service_object.dart";
part "../../../sdk/lib/io/secure_socket.dart";
part "../../../sdk/lib/io/secure_server_socket.dart";
part "../../../sdk/lib/io/security_context.dart";
part "../../../sdk/lib/io/socket.dart";
class HttpParserTest {

View File

@ -9,6 +9,16 @@ import "dart:async";
import "dart:io";
import 'dart:convert';
String localFile(path) => Platform.script.resolve(path).toFilePath();
SecurityContext serverContext = new SecurityContext()
..useCertificateChain(localFile('certificates/server_chain.pem'))
..usePrivateKey(localFile('certificates/server_key.pem'),
password: 'dartdart');
SecurityContext clientContext = new SecurityContext()
..setTrustedCertificates(file: localFile('certificates/trusted_certs.pem'));
class Server {
HttpServer server;
bool secure;
@ -19,49 +29,47 @@ class Server {
Server(this.proxyHops, this.directRequestPaths, this.secure);
Future<Server> start() {
var x = new Completer();
Future f = secure
? HttpServer.bindSecure(
"localhost", 0, certificateName: 'localhost_cert')
: HttpServer.bind("localhost", 0);
return f.then((s) {
return (secure ?
HttpServer.bindSecure("localhost", 0, serverContext) :
HttpServer.bind("localhost", 0))
.then((s) {
server = s;
x.complete(this);
server.listen((request) {
var response = request.response;
requestCount++;
// Check whether a proxy or direct connection is expected.
bool direct = directRequestPaths.fold(
false,
(prev, path) => prev ? prev : path == request.uri.path);
if (!secure && !direct && proxyHops > 0) {
Expect.isNotNull(request.headers[HttpHeaders.VIA]);
Expect.equals(1, request.headers[HttpHeaders.VIA].length);
Expect.equals(
proxyHops,
request.headers[HttpHeaders.VIA][0].split(",").length);
} else {
Expect.isNull(request.headers[HttpHeaders.VIA]);
}
var body = new StringBuffer();
request.listen(
(data) {
body.write(new String.fromCharCodes(data));
},
onDone: () {
String path = request.uri.path.substring(1);
if (path != "A") {
String content = "$path$path$path";
Expect.equals(content, body.toString());
}
response.write(request.uri.path);
response.close();
});
});
return x.future;
server.listen(requestHandler);
return this;
});
}
void requestHandler(HttpRequest request) {
var response = request.response;
requestCount++;
// Check whether a proxy or direct connection is expected.
bool direct = directRequestPaths.fold(
false,
(prev, path) => prev ? prev : path == request.uri.path);
if (!secure && !direct && proxyHops > 0) {
Expect.isNotNull(request.headers[HttpHeaders.VIA]);
Expect.equals(1, request.headers[HttpHeaders.VIA].length);
Expect.equals(
proxyHops,
request.headers[HttpHeaders.VIA][0].split(",").length);
} else {
Expect.isNull(request.headers[HttpHeaders.VIA]);
}
var body = new StringBuffer();
onRequestComplete() {
String path = request.uri.path.substring(1);
if (path != "A") {
String content = "$path$path$path";
Expect.equals(content, body.toString());
}
response.write(request.uri.path);
response.close();
}
request.listen((data) {
body.write(new String.fromCharCodes(data));
}, onDone: onRequestComplete);
}
void shutdown() {
server.close();
}
@ -336,7 +344,7 @@ void testProxy() {
setupProxyServer().then((proxyServer) {
setupServer(1, directRequestPaths: ["/4"]).then((server) {
setupServer(1, directRequestPaths: ["/4"], secure: true).then((secureServer) {
HttpClient client = new HttpClient();
HttpClient client = new HttpClient(context: clientContext);
List<String> proxy;
if (Platform.operatingSystem == "windows") {
@ -796,26 +804,22 @@ void testRealProxyAuth() {
});
}
void InitializeSSL() {
var testPkcertDatabase = Platform.script.resolve('pkcert').toFilePath();
SecureSocket.initialize(database: testPkcertDatabase,
password: 'dartdart');
}
main() {
InitializeSSL();
testInvalidProxy();
testDirectProxy();
testProxy();
testProxyIPV6();
// testProxyIPV6(); // TODO(24074): Move failing tests to separate files.
testProxyChain();
testProxyFromEnviroment();
// TODO(24074): Move failing tests to separate files.
// testProxyFromEnviroment();
// The two invocations of uses the same global variable for state -
// run one after the other.
testProxyAuthenticate(false)
.then((_) => testProxyAuthenticate(true));
// TODO(24074): Move failing tests to separate files.
// testProxyAuthenticate(false)
// .then((_) => testProxyAuthenticate(true));
// This test is not normally run. It can be used for locally testing
// with a real proxy server (e.g. Apache).
//testRealProxy();
//testRealProxyAuth();
// testRealProxy();
// testRealProxyAuth();
}

View File

@ -1,81 +0,0 @@
// Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
// Client for https_bad_certificate_test, that runs in a subprocess.
// It verifies that the client bad certificate callback works in HttpClient.
import "dart:async";
import "dart:io";
class ExpectException implements Exception {
ExpectException(this.message);
String toString() => "ExpectException: $message";
String message;
}
void expect(condition) {
if (!condition) {
throw new ExpectException('');
}
}
const HOST_NAME = "localhost";
Future runHttpClient(int port, result) async {
bool badCertificateCallback(X509Certificate certificate,
String host,
int callbackPort) {
expect(HOST_NAME == host);
expect(callbackPort == port);
expect('CN=localhost' == certificate.subject);
expect('CN=myauthority' == certificate.issuer);
expect(result != 'exception'); // Throw exception if one is requested.
if (result == 'true') return true;
if (result == 'false') return false;
return result;
}
HttpClient client = new HttpClient();
await client.getUrl(Uri.parse('https://$HOST_NAME:$port/$result'))
.then((HttpClientRequest request) {
expect(result == 'true'); // The session cache may keep the session.
return request.close();
}, onError: (e) {
expect(e is HandshakeException || e is SocketException);
});
client.badCertificateCallback = badCertificateCallback;
await client.getUrl(Uri.parse('https://$HOST_NAME:$port/$result'))
.then((HttpClientRequest request) {
expect(result == 'true');
return request.close();
}, onError: (e) {
if (result == 'false') expect (e is HandshakeException ||
e is SocketException);
else if (result == 'exception') expect (e is ExpectException ||
e is SocketException);
else {
expect (e is ArgumentError || e is SocketException);
}
});
client.badCertificateCallback = null;
await client.getUrl(Uri.parse('https://$HOST_NAME:$port/$result'))
.then((HttpClientRequest request) {
expect(result == 'true'); // The session cache may keep the session.
return request.close();
}, onError: (e) {
expect(e is HandshakeException || e is SocketException);
});
client.close();
}
void main(List<String> args) {
SecureSocket.initialize();
int port = int.parse(args[0]);
runHttpClient(port, args[1])
.then((_) => print('SUCCESS'));
}

View File

@ -4,52 +4,78 @@
// This test verifies that the bad certificate callback works in HttpClient.
import "package:expect/expect.dart";
import "package:path/path.dart";
import "dart:async";
import "dart:io";
const HOST_NAME = "localhost";
const CERTIFICATE = "localhost_cert";
import "package:expect/expect.dart";
Future<SecureServerSocket> runServer() {
SecureSocket.initialize(
database: Platform.script.resolve('pkcert').toFilePath(),
final HOST_NAME = 'localhost';
String localFile(path) => Platform.script.resolve(path).toFilePath();
SecurityContext serverContext = new SecurityContext()
..useCertificateChain(localFile('certificates/server_chain.pem'))
..usePrivateKey(localFile('certificates/server_key.pem'),
password: 'dartdart');
return HttpServer.bindSecure(
HOST_NAME, 0, backlog: 5, certificateName: 'localhost_cert')
.then((server) {
server.listen((HttpRequest request) {
request.listen((_) { }, onDone: () { request.response.close(); });
}, onError: (e) { if (e is! HandshakeException) throw e; });
return server;
});
}
class CustomException {}
main() async {
var clientScript = Platform.script
.resolve('https_bad_certificate_client.dart')
.toFilePath();
Future clientProcess(int port, String acceptCertificate) {
return Process.run(Platform.executable,
[clientScript, port.toString(), acceptCertificate])
.then((ProcessResult result) {
if (result.exitCode != 0 || !result.stdout.contains('SUCCESS')) {
print("Client failed, acceptCertificate: $acceptCertificate");
print(" stdout:");
print(result.stdout);
print(" stderr:");
print(result.stderr);
Expect.fail('Client subprocess exit code: ${result.exitCode}');
}
var HOST = (await InternetAddress.lookup(HOST_NAME)).first;
var server = await HttpServer.bindSecure(HOST, 0, serverContext, backlog: 5);
server.listen((request) {
request.listen((_) {
}, onDone: () {
request.response.close();
});
}
});
var server = await runServer();
await clientProcess(server.port, 'true');
await clientProcess(server.port, 'false');
await clientProcess(server.port, 'fisk');
await clientProcess(server.port, 'exception');
SecurityContext goodContext = new SecurityContext()
..setTrustedCertificates(file: localFile('certificates/trusted_certs.pem'));
SecurityContext badContext = new SecurityContext();
SecurityContext defaultContext = SecurityContext.defaultContext;
await runClient(server.port, goodContext, true, 'pass');
await runClient(server.port, goodContext, false, 'pass');
await runClient(server.port, goodContext, 'fisk', 'pass');
await runClient(server.port, goodContext, 'exception', 'pass');
await runClient(server.port, badContext, true, 'pass');
await runClient(server.port, badContext, false, 'fail');
await runClient(server.port, badContext, 'fisk', 'fail');
await runClient(server.port, badContext, 'exception', 'throw');
await runClient(server.port, defaultContext, true, 'pass');
await runClient(server.port, defaultContext, false, 'fail');
await runClient(server.port, defaultContext, 'fisk', 'fail');
await runClient(server.port, defaultContext, 'exception', 'throw');
server.close();
}
Future runClient(int port,
SecurityContext context,
callbackReturns,
result) async {
HttpClient client = new HttpClient(context: context);
client.badCertificateCallback = (X509Certificate certificate, host, port) {
Expect.equals('/CN=rootauthority', certificate.subject);
Expect.equals('/CN=rootauthority', certificate.issuer);
// Throw exception if one is requested.
if (callbackReturns == 'exception') throw new CustomException();
return callbackReturns;
};
try {
var request = await client.getUrl(Uri.parse('https://$HOST_NAME:$port/'));
Expect.equals('pass', result);
await request.close();
} catch (error) {
Expect.notEquals(result, 'pass');
if (result == 'fail') {
Expect.isTrue(error is HandshakeException);
} else if (result == 'throw') {
Expect.isTrue(error is CustomException);
} else {
Expect.fail('Unknown expectation $result');
}
}
}

View File

@ -10,14 +10,27 @@ import "package:expect/expect.dart";
import "package:path/path.dart";
const HOST_NAME = "localhost";
String localFile(path) => Platform.script.resolve(path).toFilePath();
SecurityContext serverContext = new SecurityContext()
..useCertificateChain(localFile('certificates/server_chain.pem'))
..usePrivateKey(localFile('certificates/server_key.pem'),
password: 'dartdart');
// TODO: Specify which client certificate roots to trust.
Function test() {
SecurityContext clientContext = new SecurityContext()
..setTrustedCertificates(file: localFile('certificates/trusted_certs.pem'))
// TODO: Set a client certificate here.
..useCertificateChain(localFile('certificates/server_chain.pem'))
..usePrivateKey(localFile('certificates/server_key.pem'),
password: 'dartdart');
void main() {
asyncStart();
HttpServer.bindSecure(HOST_NAME,
0,
serverContext,
backlog: 5,
certificateName: 'localhost_cert',
requestClientCertificate: true).then((server) {
server.listen((HttpRequest request) {
Expect.isNotNull(request.certificate);
@ -26,7 +39,7 @@ Function test() {
request.response.close();
});
HttpClient client = new HttpClient();
HttpClient client = new HttpClient(context: clientContext);
client.getUrl(Uri.parse("https://$HOST_NAME:${server.port}/"))
.then((request) => request.close())
.then((response) {
@ -44,14 +57,3 @@ Function test() {
});
});
}
void InitializeSSL() {
var testPkcertDatabase = Platform.script.resolve('pkcert').toFilePath();
SecureSocket.initialize(database: testPkcertDatabase,
password: 'dartdart');
}
void main() {
InitializeSSL();
test();
}

View File

@ -9,14 +9,23 @@ import "dart:isolate";
import "package:expect/expect.dart";
InternetAddress HOST;
const CERTIFICATE = "localhost_cert";
String localFile(path) => Platform.script.resolve(path).toFilePath();
SecurityContext serverContext = new SecurityContext()
..useCertificateChain(localFile('certificates/server_chain.pem'))
..usePrivateKey(localFile('certificates/server_key.pem'),
password: 'dartdart');
SecurityContext clientContext = new SecurityContext()
..setTrustedCertificates(file: localFile('certificates/trusted_certs.pem'));
void testListenOn() {
void test(void onDone()) {
HttpServer.bindSecure(HOST,
0,
backlog: 5,
certificateName: CERTIFICATE).then((server) {
serverContext,
backlog: 5).then((server) {
ReceivePort serverPort = new ReceivePort();
server.listen((HttpRequest request) {
request.listen(
@ -27,7 +36,7 @@ void testListenOn() {
});
});
HttpClient client = new HttpClient();
HttpClient client = new HttpClient(context: clientContext);
ReceivePort clientPort = new ReceivePort();
client.getUrl(Uri.parse("https://${HOST.host}:${server.port}/"))
.then((HttpClientRequest request) {
@ -58,16 +67,10 @@ void testListenOn() {
});
}
void InitializeSSL() {
var testPkcertDatabase = Platform.script.resolve('pkcert').toFilePath();
SecureSocket.initialize(database: testPkcertDatabase,
password: 'dartdart');
}
void testEarlyClientClose() {
HttpServer.bindSecure(HOST,
0,
certificateName: 'localhost_cert').then((server) {
serverContext).then((server) {
server.listen(
(request) {
String name = Platform.script.toFilePath();
@ -96,7 +99,6 @@ void testEarlyClientClose() {
}
void main() {
InitializeSSL();
InternetAddress.lookup("localhost").then((hosts) {
HOST = hosts.first;
testListenOn();

View File

@ -15,9 +15,9 @@ class ExpectException implements Exception {
String message;
}
void expect(condition) {
void expect(condition, message) {
if (!condition) {
throw new ExpectException('');
throw new ExpectException(message);
}
}
@ -31,16 +31,19 @@ Future runClients(int port) {
testFutures.add(
client.getUrl(Uri.parse('https://$HOST_NAME:$port/'))
.then((HttpClientRequest request) {
expect(false);
expect(false, "Request succeeded");
}, onError: (e) {
expect(e is HandshakeException || e is SocketException);
// Remove ArgumentError once null default context is supported.
expect(e is HandshakeException ||
e is SocketException ||
e is ArgumentError,
"Error is wrong type: $e");
}));
}
return Future.wait(testFutures);
}
void main(List<String> args) {
SecureSocket.initialize();
runClients(int.parse(args[0]))
.then((_) => print('SUCCESS'));
}

View File

@ -13,13 +13,19 @@ import "dart:io";
const HOST_NAME = "localhost";
const CERTIFICATE = "localhost_cert";
Future<SecureServerSocket> runServer() {
SecureSocket.initialize(
database: Platform.script.resolve('pkcert').toFilePath(),
password: 'dartdart');
String localFile(path) => Platform.script.resolve(path).toFilePath();
SecurityContext untrustedServerContext = new SecurityContext()
..useCertificateChain(localFile('certificates/untrusted_server_chain.pem'))
..usePrivateKey(localFile('certificates/untrusted_server_key.pem'),
password: 'dartdart');
SecurityContext clientContext = new SecurityContext()
..setTrustedCertificates(file: localFile('certificates/trusted_certs.pem'));
Future<SecureServerSocket> runServer() {
return HttpServer.bindSecure(
HOST_NAME, 0, backlog: 5, certificateName: 'localhost_cert')
HOST_NAME, 0, untrustedServerContext, backlog: 5)
.then((server) {
server.listen((HttpRequest request) {
request.listen((_) { }, onDone: () { request.response.close(); });

View File

@ -1,16 +0,0 @@
This is a certificate database used by Dart for testing purposes.
It is created as a certificate database by NSS (Network Security Services),
a library from Mozilla, using the certutil tool. It uses a cert9.db file,
rather than a cert8.db file, so the database directory must be specified with
"sql:" in front of the directory path, or the environment variable
NSS_DEFAULT_DB_TYPE must be set to "sql".
The password for the key database is "dartdart".
The database contains a root certificate from Equifax, used to verify the
client https connection to www.google.dk. It contains a self-signed
certificate for a local certificate authority myauthority_cert, and a
server certificate for localhost called localhost_cert, signed by
myauthority_cert. It contains the key for localhost_cert, but
not the key for myauthority_cert.

Binary file not shown.

Binary file not shown.

View File

@ -14,7 +14,15 @@ import "package:async_helper/async_helper.dart";
import "package:expect/expect.dart";
InternetAddress HOST;
const CERTIFICATE = "localhost_cert";
String localFile(path) => Platform.script.resolve(path).toFilePath();
SecurityContext serverContext = new SecurityContext()
..useCertificateChain(localFile('certificates/server_chain.pem'))
..usePrivateKey(localFile('certificates/server_key.pem'),
password: 'dartdart');
SecurityContext clientContext = new SecurityContext()
..setTrustedCertificates(file: localFile('certificates/trusted_certs.pem'));
void testCloseOneEnd(String toClose) {
asyncStart();
@ -25,7 +33,7 @@ void testCloseOneEnd(String toClose) {
.then((_) {
asyncEnd();
});
RawSecureServerSocket.bind(HOST, 0, CERTIFICATE).then((server) {
RawSecureServerSocket.bind(HOST, 0, serverContext).then((server) {
server.listen((serverConnection) {
serverConnection.listen((event) {
if (toClose == "server" || event == RawSocketEvent.READ_CLOSED) {
@ -39,7 +47,8 @@ void testCloseOneEnd(String toClose) {
onDone: () {
serverDone.complete(null);
});
RawSecureSocket.connect(HOST, server.port).then((clientConnection) {
RawSecureSocket.connect(HOST, server.port, context: clientContext)
.then((clientConnection) {
clientConnection.listen((event){
if (toClose == "client" || event == RawSocketEvent.READ_CLOSED) {
clientConnection.shutdown(SocketDirection.SEND);
@ -55,8 +64,9 @@ void testCloseOneEnd(String toClose) {
void testCloseBothEnds() {
asyncStart();
RawSecureServerSocket.bind(HOST, 0, CERTIFICATE).then((server) {
var clientEndFuture = RawSecureSocket.connect(HOST, server.port);
RawSecureServerSocket.bind(HOST, 0, serverContext).then((server) {
var clientEndFuture =
RawSecureSocket.connect(HOST, server.port, context: clientContext);
server.listen((serverEnd) {
clientEndFuture.then((clientEnd) {
clientEnd.close();
@ -77,7 +87,7 @@ testPauseServerSocket() {
RawSecureServerSocket.bind(HOST,
0,
CERTIFICATE,
serverContext,
backlog: 2 * socketCount).then((server) {
Expect.isTrue(server.port > 0);
var subscription;
@ -96,7 +106,8 @@ testPauseServerSocket() {
subscription.pause();
var connectCount = 0;
for (int i = 0; i < socketCount; i++) {
RawSecureSocket.connect(HOST, server.port).then((connection) {
RawSecureSocket.connect(HOST, server.port, context: clientContext)
.then((connection) {
connection.shutdown(SocketDirection.SEND);
});
}
@ -104,7 +115,8 @@ testPauseServerSocket() {
subscription.resume();
resumed = true;
for (int i = 0; i < socketCount; i++) {
RawSecureSocket.connect(HOST, server.port).then((connection) {
RawSecureSocket.connect(HOST, server.port, context: clientContext)
.then((connection) {
connection.shutdown(SocketDirection.SEND);
});
}
@ -117,7 +129,7 @@ testCloseServer() {
asyncStart();
List ends = [];
RawSecureServerSocket.bind(HOST, 0, CERTIFICATE).then((server) {
RawSecureServerSocket.bind(HOST, 0, serverContext).then((server) {
Expect.isTrue(server.port > 0);
void checkDone() {
if (ends.length < 2 * socketCount) return;
@ -134,7 +146,8 @@ testCloseServer() {
});
for (int i = 0; i < socketCount; i++) {
RawSecureSocket.connect(HOST, server.port).then((connection) {
RawSecureSocket.connect(HOST, server.port, context: clientContext)
.then((connection) {
ends.add(connection);
checkDone();
});
@ -145,10 +158,6 @@ testCloseServer() {
main() {
asyncStart();
var certificateDatabase = Platform.script.resolve('pkcert').toFilePath();
SecureSocket.initialize(database: certificateDatabase,
password: 'dartdart',
useBuiltinRoots: false);
InternetAddress.lookup("localhost").then((hosts) {
HOST = hosts.first;
runTests();

View File

@ -20,17 +20,13 @@ const CERTIFICATE = "localhost_cert";
void testArguments() {
bool isArgOrTypeError(e) => e is ArgumentError || e is TypeError;
Expect.throws(() =>
RawSecureServerSocket.bind(SERVER_ADDRESS, 65536, CERTIFICATE),
RawSecureServerSocket.bind(SERVER_ADDRESS, 65536, null),
isArgOrTypeError);
Expect.throws(() =>
RawSecureServerSocket.bind(SERVER_ADDRESS, -1, CERTIFICATE),
RawSecureServerSocket.bind(SERVER_ADDRESS, -1, null),
isArgOrTypeError);
Expect.throws(() => RawSecureServerSocket.bind(SERVER_ADDRESS, 0,
CERTIFICATE, backlog: -1),
isArgOrTypeError);
Expect.throws(() => RawSecureSocket.connect(SERVER_ADDRESS, 3456,
sendClientCertificate: true,
certificateName: 12.3),
null, backlog: -1),
isArgOrTypeError);
Expect.throws(() => RawSecureSocket.connect(SERVER_ADDRESS, null),
isArgOrTypeError);
@ -42,12 +38,6 @@ void testArguments() {
isArgOrTypeError);
Expect.throws(() => RawSecureSocket.connect(null, 0),
isArgOrTypeError);
Expect.throws(() => RawSecureSocket.connect(SERVER_ADDRESS, 0,
certificateName: 77),
isArgOrTypeError);
Expect.throws(() => RawSecureSocket.connect(SERVER_ADDRESS, 0,
sendClientCertificate: 'fisk'),
isArgOrTypeError);
Expect.throws(() => RawSecureSocket.connect(SERVER_ADDRESS, 0,
onBadCertificate: 'hund'),
isArgOrTypeError);
@ -55,9 +45,5 @@ void testArguments() {
main() {
var certificateDatabase = Platform.script.resolve('pkcert').toFilePath();
SecureSocket.initialize(database: certificateDatabase,
password: 'dartdart',
useBuiltinRoots: false);
testArguments();
}

View File

@ -14,11 +14,19 @@ import "package:async_helper/async_helper.dart";
import "package:expect/expect.dart";
InternetAddress HOST;
const CERTIFICATE = "localhost_cert";
String localFile(path) => Platform.script.resolve(path).toFilePath();
SecurityContext serverContext = new SecurityContext()
..useCertificateChain(localFile('certificates/server_chain.pem'))
..usePrivateKey(localFile('certificates/server_key.pem'),
password: 'dartdart');
SecurityContext clientContext = new SecurityContext()
..setTrustedCertificates(file: localFile('certificates/trusted_certs.pem'));
void testSimpleBind() {
asyncStart();
RawSecureServerSocket.bind(HOST, 0, CERTIFICATE).then((s) {
RawSecureServerSocket.bind(HOST, 0, serverContext).then((s) {
Expect.isTrue(s.port > 0);
s.close();
asyncEnd();
@ -30,7 +38,7 @@ void testInvalidBind() {
// Bind to a unknown DNS name.
asyncStart();
RawSecureServerSocket.bind("ko.faar.__hest__", 0, CERTIFICATE).then((_) {
RawSecureServerSocket.bind("ko.faar.__hest__", 0, serverContext).then((_) {
Expect.fail("Failure expected");
}).catchError((error) {
Expect.isTrue(error is SocketException);
@ -39,7 +47,7 @@ void testInvalidBind() {
// Bind to an unavaliable IP-address.
asyncStart();
RawSecureServerSocket.bind("8.8.8.8", 0, CERTIFICATE).then((_) {
RawSecureServerSocket.bind("8.8.8.8", 0, serverContext).then((_) {
Expect.fail("Failure expected");
}).catchError((error) {
Expect.isTrue(error is SocketException);
@ -48,10 +56,10 @@ void testInvalidBind() {
// Bind to a port already in use.
asyncStart();
RawSecureServerSocket.bind(HOST, 0, CERTIFICATE).then((s) {
RawSecureServerSocket.bind(HOST, 0, serverContext).then((s) {
RawSecureServerSocket.bind(HOST,
s.port,
CERTIFICATE).then((t) {
serverContext).then((t) {
s.close();
t.close();
Expect.fail("Multiple listens on same port");
@ -64,12 +72,14 @@ void testInvalidBind() {
});
}
void testSimpleConnect(String certificate) {
void testSimpleConnect() {
asyncStart();
RawSecureServerSocket.bind(HOST, 0, certificate).then((server) {
var clientEndFuture = RawSecureSocket.connect(HOST, server.port);
RawSecureServerSocket.bind(HOST, 0, serverContext).then((server) {
var clientEndFuture =
RawSecureSocket.connect(HOST, server.port, context: clientContext);
server.listen((serverEnd) {
clientEndFuture.then((clientEnd) {
// TODO(whesse): Shutdown(SEND) not supported on secure sockets.
clientEnd.shutdown(SocketDirection.SEND);
serverEnd.shutdown(SocketDirection.SEND);
server.close();
@ -79,10 +89,11 @@ void testSimpleConnect(String certificate) {
});
}
void testSimpleConnectFail(String certificate, bool cancelOnError) {
void testSimpleConnectFail(SecurityContext context, bool cancelOnError) {
asyncStart();
RawSecureServerSocket.bind(HOST, 0, certificate).then((server) {
var clientEndFuture = RawSecureSocket.connect(HOST, server.port)
RawSecureServerSocket.bind(HOST, 0, context).then((server) {
var clientEndFuture =
RawSecureSocket.connect(HOST, server.port, context: clientContext)
.then((clientEnd) {
Expect.fail("No client connection expected.");
})
@ -94,7 +105,7 @@ void testSimpleConnectFail(String certificate, bool cancelOnError) {
Expect.fail("No server connection expected.");
},
onError: (error) {
Expect.isTrue(error is CertificateException);
Expect.isTrue(error is HandshakeException);
clientEndFuture.then((_) {
if (!cancelOnError) server.close();
asyncEnd();
@ -106,9 +117,10 @@ void testSimpleConnectFail(String certificate, bool cancelOnError) {
void testServerListenAfterConnect() {
asyncStart();
RawSecureServerSocket.bind(HOST, 0, CERTIFICATE).then((server) {
RawSecureServerSocket.bind(HOST, 0, serverContext).then((server) {
Expect.isTrue(server.port > 0);
var clientEndFuture = RawSecureSocket.connect(HOST, server.port);
var clientEndFuture =
RawSecureSocket.connect(HOST, server.port, context: clientContext);
new Timer(const Duration(milliseconds: 500), () {
server.listen((serverEnd) {
clientEndFuture.then((clientEnd) {
@ -422,15 +434,17 @@ void testSimpleReadWrite({bool listenSecure,
Future<RawSecureSocket> connectClient(int port) {
if (connectSecure) {
return RawSecureSocket.connect(HOST, port);
return RawSecureSocket.connect(HOST, port, context: clientContext);
} else if (!handshakeBeforeSecure) {
return RawSocket.connect(HOST, port).then((socket) {
return RawSecureSocket.secure(socket);
return RawSecureSocket.secure(socket, context: clientContext);
});
} else {
return RawSocket.connect(HOST, port).then((socket) {
return runClientHandshake(socket).then((subscription) {
return RawSecureSocket.secure(socket, subscription: subscription);
return RawSecureSocket.secure(socket,
context: clientContext,
subscription: subscription);
});
});
}
@ -441,14 +455,14 @@ void testSimpleReadWrite({bool listenSecure,
if (listenSecure) {
runServer(client).then((_) => server.close());
} else if (!handshakeBeforeSecure) {
RawSecureSocket.secureServer(client, CERTIFICATE).then((client) {
RawSecureSocket.secureServer(client, serverContext).then((client) {
runServer(client).then((_) => server.close());
});
} else {
runServerHandshake(client).then((secure) {
RawSecureSocket.secureServer(
client,
CERTIFICATE,
serverContext,
subscription: secure[0],
bufferedData: secure[1]).then((client) {
runServer(client).then((_) => server.close());
@ -465,7 +479,7 @@ void testSimpleReadWrite({bool listenSecure,
if (listenSecure) {
RawSecureServerSocket.bind(
HOST, 0, CERTIFICATE).then(serverReady);
HOST, 0, serverContext).then(serverReady);
} else {
RawServerSocket.bind(HOST, 0).then(serverReady);
}
@ -490,7 +504,7 @@ testPausedSecuringSubscription(bool pausedServer, bool pausedClient) {
}
try {
RawSecureSocket.secureServer(
client, CERTIFICATE, subscription: subscription)
client, serverContext, subscription: subscription)
.catchError((_) {})
.whenComplete(() {
if (pausedServer) {
@ -543,10 +557,6 @@ testPausedSecuringSubscription(bool pausedServer, bool pausedClient) {
main() {
asyncStart();
var certificateDatabase = Platform.script.resolve('pkcert').toFilePath();
SecureSocket.initialize(database: certificateDatabase,
password: 'dartdart',
useBuiltinRoots: false);
InternetAddress.lookup("localhost").then((hosts) {
HOST = hosts.first;
runTests();
@ -557,12 +567,22 @@ main() {
runTests() {
testSimpleBind();
testInvalidBind();
testSimpleConnect(CERTIFICATE);
testSimpleConnect("CN=localhost");
testSimpleConnectFail("not_a_nickname", false);
testSimpleConnectFail("CN=notARealDistinguishedName", false);
testSimpleConnectFail("not_a_nickname", true);
testSimpleConnectFail("CN=notARealDistinguishedName", true);
testSimpleConnect();
SecurityContext context = new SecurityContext();
testSimpleConnectFail(context, false);
testSimpleConnectFail(context, true);
var chain =
Platform.script.resolve('certificates/untrusted_server_chain.pem')
.toFilePath();
context.useCertificateChain(chain);
testSimpleConnectFail(context, false);
testSimpleConnectFail(context, true);
var key =
Platform.script.resolve('certificates/untrusted_server_key.pem')
.toFilePath();
context.usePrivateKey(key, password: 'dartdart');
testSimpleConnectFail(context, false);
testSimpleConnectFail(context, true);
testServerListenAfterConnect();
testSimpleReadWrite(listenSecure: true,
@ -575,11 +595,13 @@ runTests() {
handshakeBeforeSecure: false,
postponeSecure: false,
dropReads: false);
testSimpleReadWrite(listenSecure: false,
connectSecure: true,
handshakeBeforeSecure: false,
postponeSecure: false,
dropReads: false);
testSimpleReadWrite(listenSecure: false,
connectSecure: false,
handshakeBeforeSecure: false,

View File

@ -13,12 +13,22 @@ import "dart:async";
import "dart:io";
import "dart:isolate";
String localFile(path) => Platform.script.resolve(path).toFilePath();
SecurityContext serverContext = new SecurityContext()
..useCertificateChain(localFile('certificates/server_chain.pem'))
..usePrivateKey(localFile('certificates/server_key.pem'),
password: 'dartdart');
SecurityContext clientContext = new SecurityContext()
..setTrustedCertificates(file: localFile('certificates/trusted_certs.pem'));
Future<HttpServer> startServer() {
return HttpServer.bindSecure(
"localhost",
0,
backlog: 5,
certificateName: 'localhost_cert').then((server) {
serverContext,
backlog: 5).then((server) {
server.listen((HttpRequest request) {
request.listen(
(_) { },
@ -34,77 +44,72 @@ Future<HttpServer> startServer() {
});
}
void InitializeSSL() {
var testPkcertDatabase = Platform.script.resolve('pkcert').toFilePath();
SecureSocket.initialize(database: testPkcertDatabase,
password: 'dartdart');
}
void main() {
main() async {
List<int> message = "GET / HTTP/1.0\r\nHost: localhost\r\n\r\n".codeUnits;
int written = 0;
List<int> body = <int>[];
InitializeSSL();
startServer().then((server) {
RawSecureSocket.connect("localhost", server.port).then((socket) {
StreamSubscription subscription;
bool paused = false;
bool readEventsTested = false;
bool readEventsPaused = false;
var server = await startServer();
var socket = await RawSecureSocket.connect("localhost",
server.port,
context: clientContext);
StreamSubscription subscription;
bool paused = false;
bool readEventsTested = false;
bool readEventsPaused = false;
void runPauseTest() {
subscription.pause();
paused = true;
new Timer(const Duration(milliseconds: 500), () {
paused = false;
subscription.resume();
});
}
void runReadEventTest() {
if (readEventsTested) return;
readEventsTested = true;
socket.readEventsEnabled = false;
readEventsPaused = true;
new Timer(const Duration(milliseconds: 500), () {
readEventsPaused = false;
socket.readEventsEnabled = true;
});
}
subscription = socket.listen(
(RawSocketEvent event) {
Expect.isFalse(paused);
switch (event) {
case RawSocketEvent.READ:
Expect.isFalse(readEventsPaused);
runReadEventTest();
body.addAll(socket.read());
break;
case RawSocketEvent.WRITE:
written +=
socket.write(message, written, message.length - written);
if (written < message.length) {
socket.writeEventsEnabled = true;
} else {
socket.shutdown(SocketDirection.SEND);
runPauseTest();
}
break;
case RawSocketEvent.READ_CLOSED:
Expect.isTrue(body.length > 100);
Expect.equals(72, body[0]);
Expect.equals(9, body[body.length - 1]);
server.close();
break;
default: throw "Unexpected event $event";
}
},
onError: (e, trace) {
String msg = "onError handler of RawSecureSocket stream hit: $e";
if (trace != null) msg += "\nStackTrace: $trace";
Expect.fail(msg);
});
void runPauseTest() {
subscription.pause();
paused = true;
new Timer(const Duration(milliseconds: 500), () {
paused = false;
subscription.resume();
});
});
}
void runReadEventTest() {
if (readEventsTested) return;
readEventsTested = true;
socket.readEventsEnabled = false;
readEventsPaused = true;
new Timer(const Duration(milliseconds: 500), () {
readEventsPaused = false;
socket.readEventsEnabled = true;
});
}
void handleRawEvent(RawSocketEvent event) {
Expect.isFalse(paused);
switch (event) {
case RawSocketEvent.READ:
Expect.isFalse(readEventsPaused);
runReadEventTest();
body.addAll(socket.read());
break;
case RawSocketEvent.WRITE:
written +=
socket.write(message, written, message.length - written);
if (written < message.length) {
socket.writeEventsEnabled = true;
} else {
socket.shutdown(SocketDirection.SEND);
runPauseTest();
}
break;
case RawSocketEvent.READ_CLOSED:
Expect.isTrue(body.length > 100);
Expect.equals(72, body.first);
Expect.equals(9, body.last);
server.close();
break;
default: throw "Unexpected event $event";
}
}
subscription = socket.listen(
handleRawEvent,
onError: (e, trace) {
String msg = "onError handler of RawSecureSocket stream hit: $e";
if (trace != null) msg += "\nStackTrace: $trace";
Expect.fail(msg);
});
}

View File

@ -13,69 +13,61 @@ import "dart:async";
import "dart:io";
import "dart:isolate";
Future<HttpServer> startServer() {
return HttpServer.bindSecure(
"localhost",
0,
backlog: 5,
certificateName: 'localhost_cert').then((server) {
server.listen((HttpRequest request) {
request.listen(
(_) { },
onDone: () {
request.response.contentLength = 100;
for (int i = 0; i < 10; i++) {
request.response.add([0, 1, 2, 3, 4, 5, 6, 7, 8, 9]);
}
request.response.close();
});
});
return server;
});
}
String localFile(path) => Platform.script.resolve(path).toFilePath();
void InitializeSSL() {
var testPkcertDatabase = Platform.script.resolve('pkcert').toFilePath();
SecureSocket.initialize(database: testPkcertDatabase,
password: 'dartdart');
}
SecurityContext serverContext = new SecurityContext()
..useCertificateChain(localFile('certificates/server_chain.pem'))
..usePrivateKey(localFile('certificates/server_key.pem'),
password: 'dartdart');
void main() {
SecurityContext clientContext = new SecurityContext()
..setTrustedCertificates(file: localFile('certificates/trusted_certs.pem'));
main() async {
List<int> message = "GET / HTTP/1.0\r\nHost: localhost\r\n\r\n".codeUnits;
int written = 0;
List<int> body = <int>[];
InitializeSSL();
startServer().then((server) {
RawSecureSocket.connect("localhost", server.port).then((socket) {
socket.listen(
(RawSocketEvent event) {
switch (event) {
case RawSocketEvent.READ:
body.addAll(socket.read());
break;
case RawSocketEvent.WRITE:
written +=
socket.write(message, written, message.length - written);
if (written < message.length) {
socket.writeEventsEnabled = true;
} else {
socket.shutdown(SocketDirection.SEND);
}
break;
case RawSocketEvent.READ_CLOSED:
Expect.isTrue(body.length > 100, "$body\n${body.length}");
Expect.equals(72, body[0]);
Expect.equals(9, body[body.length - 1]);
server.close();
break;
default: throw "Unexpected event $event";
}
},
onError: (e, trace) {
String msg = "onError handler of RawSecureSocket stream hit $e";
if (trace != null) msg += "\nStackTrace: $trace";
Expect.fail(msg);
});
});
var server = await HttpServer.bindSecure(
"localhost",
0,
serverContext,
backlog: 5);
server.listen((HttpRequest request) async {
await request.drain();
request.response.contentLength = 100;
for (int i = 0; i < 10; i++) {
request.response.add([0, 1, 2, 3, 4, 5, 6, 7, 8, 9]);
}
request.response.close();
});
var socket = await RawSecureSocket.connect("localhost",
server.port,
context: clientContext);
socket.listen((RawSocketEvent event) {
switch (event) {
case RawSocketEvent.READ:
body.addAll(socket.read());
break;
case RawSocketEvent.WRITE:
written +=
socket.write(message, written, message.length - written);
if (written < message.length) {
socket.writeEventsEnabled = true;
} else {
socket.shutdown(SocketDirection.SEND);
}
break;
case RawSocketEvent.READ_CLOSED:
Expect.isTrue(body.length > 100, "$body\n${body.length}");
Expect.equals(72, body[0]);
Expect.equals(9, body[body.length - 1]);
server.close();
break;
default: throw "Unexpected event $event";
}
}, onError: (e, trace) {
String msg = "onError handler of RawSecureSocket stream hit $e";
if (trace != null) msg += "\nStackTrace: $trace";
Expect.fail(msg);
});
}

View File

@ -10,6 +10,16 @@ import "dart:async";
import "dart:io";
import "dart:typed_data";
String localFile(path) => Platform.script.resolve(path).toFilePath();
SecurityContext serverContext = new SecurityContext()
..useCertificateChain(localFile('certificates/server_chain.pem'))
..usePrivateKey(localFile('certificates/server_key.pem'),
password: 'dartdart');
SecurityContext clientContext = new SecurityContext()
..setTrustedCertificates(file: localFile('certificates/trusted_certs.pem'));
// 10 KiB of i%256 data.
Uint8List DATA = new Uint8List.fromList(
new List.generate(10 * 1024, (i) => i % 256));
@ -17,63 +27,54 @@ Uint8List DATA = new Uint8List.fromList(
Future<SecureServerSocket> startServer() {
return SecureServerSocket.bind("localhost",
0,
'localhost_cert').then((server) {
server.listen((SecureSocket request) {
request.drain().then((_) {
request
..add(DATA)
..close();
});
serverContext).then((server) {
server.listen((SecureSocket request) async {
await request.drain();
request..add(DATA)..close();
});
return server;
});
}
void InitializeSSL() {
var testPkcertDatabase = Platform.script.resolve('pkcert').toFilePath();
SecureSocket.initialize(database: testPkcertDatabase,
password: 'dartdart');
}
void main() {
InitializeSSL();
main() async {
asyncStart();
startServer().then((SecureServerSocket server) {
RawSecureSocket.connect("localhost", server.port).then((socket) {
List<int> body = <int>[];
var server = await SecureServerSocket.bind("localhost", 0, serverContext);
server.listen((SecureSocket request) async {
await request.drain();
request..add(DATA)..close();
});
// Close our end, since we're not sending data.
socket.shutdown(SocketDirection.SEND);
var socket = await RawSecureSocket.connect("localhost",
server.port,
context: clientContext);
List<int> body = <int>[];
// Close our end, since we're not sending data.
socket.shutdown(SocketDirection.SEND);
socket.listen((RawSocketEvent event) {
switch (event) {
case RawSocketEvent.READ:
// NOTE: We have a very low prime number here. The internal
// ring buffers will not have a size of 3. This means that
// we'll reach the point where we would like to read 1/2 bytes
// at the end and then wrap around and read the next 2/1 bytes.
// [This will ensure we trigger the bug.]
body.addAll(socket.read(3));
break;
case RawSocketEvent.WRITE:
break;
case RawSocketEvent.READ_CLOSED:
break;
default: throw "Unexpected event $event";
}
},
onError: (e, _) {
Expect.fail('Unexpected error: $e');
},
onDone: () {
Expect.equals(body.length, DATA.length);
for (int i = 0; i < body.length; i++) {
Expect.equals(body[i], DATA[i]);
}
server.close();
asyncEnd();
});
});
socket.listen((RawSocketEvent event) {
switch (event) {
case RawSocketEvent.READ:
// NOTE: We have a very low prime number here. The internal
// ring buffers will not have a size of 3. This means that
// we'll reach the point where we would like to read 1/2 bytes
// at the end and then wrap around and read the next 2/1 bytes.
// [This will ensure we trigger the bug.]
body.addAll(socket.read(3));
break;
case RawSocketEvent.WRITE:
break;
case RawSocketEvent.READ_CLOSED:
break;
default: throw "Unexpected event $event";
}
}, onError: (e, _) {
Expect.fail('Unexpected error: $e');
}, onDone: () {
Expect.equals(body.length, DATA.length);
for (int i = 0; i < body.length; i++) {
Expect.equals(body[i], DATA[i]);
}
server.close();
asyncEnd();
});
}

View File

@ -1,58 +0,0 @@
// Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
// Client for secure_bad_certificate_test, that runs in a subprocess.
// The test verifies that the client bad certificate callback works.
import "dart:async";
import "dart:io";
class ExpectException implements Exception {
ExpectException(this.message);
String toString() => "ExpectException: $message";
String message;
}
void expect(condition) {
if (!condition) {
throw new ExpectException('');
}
}
const HOST_NAME = "localhost";
void runClient(int port, result) {
bool badCertificateCallback(X509Certificate certificate) {
expect('CN=localhost' == certificate.subject);
expect('CN=myauthority' == certificate.issuer);
expect(result != 'exception'); // Throw exception if one is requested.
if (result == 'true') result = true;
if (result == 'false') result = false;
return result;
}
SecureSocket.connect(HOST_NAME,
port,
onBadCertificate: badCertificateCallback)
.then((SecureSocket socket) {
expect(result);
socket.close();
},
onError: (error) {
expect(result != true);
if (result == false) {
expect(error is HandshakeException);
} else if (result == 'exception') {
expect(error is ExpectException);
} else {
expect(error is ArgumentError);
}
});
}
void main(List<String> args) {
SecureSocket.initialize();
runClient(int.parse(args[0]), args[1]);
}

View File

@ -4,59 +4,81 @@
// This test verifies that the bad certificate callback works.
import "package:expect/expect.dart";
import "package:path/path.dart";
import "dart:async";
import "dart:io";
const HOST_NAME = "localhost";
const CERTIFICATE = "localhost_cert";
import "package:expect/expect.dart";
final HOST_NAME = 'localhost';
String certificateDatabase() => Platform.script.resolve('pkcert').toFilePath();
String localFile(path) => Platform.script.resolve(path).toFilePath();
Future<SecureServerSocket> runServer() {
SecureSocket.initialize(database: certificateDatabase(),
password: 'dartdart');
SecurityContext serverContext = new SecurityContext()
..useCertificateChain(localFile('certificates/server_chain.pem'))
..usePrivateKey(localFile('certificates/server_key.pem'),
password: 'dartdart');
return SecureServerSocket.bind(HOST_NAME, 0, CERTIFICATE)
.then((SecureServerSocket server) {
server.listen((SecureSocket socket) {
socket.listen((_) { },
onDone: () {
socket.close();
});
}, onError: (e) => Expect.isTrue(e is HandshakeException));
return server;
});
class CustomException {}
main() async {
var HOST = (await InternetAddress.lookup(HOST_NAME)).first;
var server = await SecureServerSocket.bind(HOST_NAME, 0, serverContext);
server.listen((SecureSocket socket) {
socket.listen((_) {}, onDone: () {
socket.close();
});
}, onError: (e) { if (e is! HandshakeException) throw e; });
SecurityContext goodContext = new SecurityContext()
..setTrustedCertificates(file: localFile('certificates/trusted_certs.pem'));
SecurityContext badContext = new SecurityContext();
SecurityContext defaultContext = SecurityContext.defaultContext;
await runClient(server.port, goodContext, true, 'pass');
await runClient(server.port, goodContext, false, 'pass');
await runClient(server.port, goodContext, 'fisk', 'pass');
await runClient(server.port, goodContext, 'exception', 'pass');
await runClient(server.port, badContext, true, 'pass');
await runClient(server.port, badContext, false, 'fail');
await runClient(server.port, badContext, 'fisk', 'fail');
await runClient(server.port, badContext, 'exception', 'throw');
await runClient(server.port, defaultContext, true, 'pass');
await runClient(server.port, defaultContext, false, 'fail');
await runClient(server.port, defaultContext, 'fisk', 'fail');
await runClient(server.port, defaultContext, 'exception', 'throw');
server.close();
}
void main() {
var clientScript = Platform.script
.resolve('secure_bad_certificate_client.dart')
.toFilePath();
Future clientProcess(int port, String acceptCertificate) {
return Process.run(Platform.executable,
[clientScript, port.toString(), acceptCertificate])
.then((ProcessResult result) {
if (result.exitCode != 0) {
print("Client failed, stdout:");
print(result.stdout);
print(" stderr:");
print(result.stderr);
Expect.fail('Client subprocess exit code: ${result.exitCode}');
}
});
Future runClient(int port,
SecurityContext context,
callbackReturns,
result) async {
badCertificateCallback(X509Certificate certificate) {
Expect.equals('/CN=rootauthority', certificate.subject);
Expect.equals('/CN=rootauthority', certificate.issuer);
// Throw exception if one is requested.
if (callbackReturns == 'exception') throw new CustomException();
return callbackReturns;
}
runServer().then((server) {
Future.wait([clientProcess(server.port, 'true'),
clientProcess(server.port, 'false'),
clientProcess(server.port, 'fisk'),
clientProcess(server.port, 'exception')]).then((_) {
server.close();
});
});
}
try {
var socket = await SecureSocket.connect(
HOST_NAME,
port,
context: context,
onBadCertificate: badCertificateCallback);
Expect.equals('pass', result); // Is rethrown below
await socket.close();
} catch (error) {
if (error is ExpectException) rethrow;
Expect.notEquals(result, 'pass');
if (result == 'fail') {
Expect.isTrue(error is HandshakeException || error is ArgumentError);
} else if (result == 'throw') {
Expect.isTrue(error is CustomException);
} else {
Expect.fail('Unknown expectation $result');
}
}
}

View File

@ -7,86 +7,33 @@ import "dart:async";
import "package:async_helper/async_helper.dart";
import "package:expect/expect.dart";
import "package:path/path.dart";
void main(List<String> args) {
if (!args.contains('--child')) {
runAllTestsInChildProcesses();
} else {
InitializeSSL(useDatabase: args.contains('--database'),
useBuiltinRoots: args.contains('--builtin-roots'));
testGoogleUrl(args.contains('--builtin-roots'));
}
}
void InitializeSSL({bool useDatabase, bool useBuiltinRoots}) {
// If the built-in root certificates aren't loaded, the connection
// should signal an error. Even when an external database is loaded,
// they should not be loaded.
if (useDatabase) {
var certificateDatabase = Platform.script.resolve('pkcert').toFilePath();
SecureSocket.initialize(database: certificateDatabase,
password: 'dartdart',
useBuiltinRoots: useBuiltinRoots);
} else {
SecureSocket.initialize(useBuiltinRoots: useBuiltinRoots);
}
}
void testGoogleUrl(bool expectSuccess) {
Future testGoogleUrl(SecurityContext context, String outcome) async {
var client = new HttpClient(context: context);
// We need to use an external server that is backed by a
// built-in root certificate authority.
// First, check if the lookup fails. If not then run the test.
InternetAddress.lookup('www.google.com').then((_) {
HttpClient client = new HttpClient();
client.getUrl(Uri.parse('https://www.google.com'))
.then((request) {
request.followRedirects = false;
return request.close();
})
.then((response) {
Expect.isTrue(expectSuccess, "Unexpected successful connection");
print('SUCCESS');
return response.drain().catchError((_) {});
})
.catchError((error) {
// Allow SocketExceptions if www.google.com is unreachable or down.
Expect.isTrue((!expectSuccess && error is HandshakeException) ||
error is SocketException);
print('SUCCESS');
})
.whenComplete(client.close);
},
onError: (e) {
// Lookup failed.
Expect.isTrue(e is SocketException);
print('SUCCESS');
});
try {
// First, check if the lookup works.
await InternetAddress.lookup('www.google.com');
var request = await client.getUrl(Uri.parse('https://www.google.com'));
request.followRedirects = false;
var response = await request.close();
Expect.equals('pass', outcome, 'Unexpected successful connection');
try { await response.drain(); } catch (e) { }
} on HandshakeException {
Expect.equals('fail', outcome, 'Unexpected failed connection');
} on SocketException {
// Lookup failed or connection failed. Don't report a failure.
} finally {
client.close();
}
}
void runAllTestsInChildProcesses() {
Future runChild(List<String> scriptArguments) {
return Process.run(Platform.executable,
[]..addAll(Platform.executableArguments)
..add(Platform.script.toFilePath())
..addAll(scriptArguments))
.then((ProcessResult result) {
if (result.exitCode != 0 || !result.stdout.contains('SUCCESS')) {
print("Client failed");
print(" stdout:");
print(result.stdout);
print(" stderr:");
print(result.stderr);
Expect.fail('Client subprocess exit code: ${result.exitCode}');
}
});
}
main() async {
asyncStart();
Future.wait([runChild(['--child']),
runChild(['--child', '--database']),
runChild(['--child', '--builtin-roots']),
runChild(['--child', '--builtin-roots', '--database'])])
.then((_) => asyncEnd());
}
await testGoogleUrl(null, "pass");
await testGoogleUrl(SecurityContext.defaultContext, "pass");
await testGoogleUrl(new SecurityContext(), "fail");
asyncEnd();
}

View File

@ -13,12 +13,21 @@ import "dart:io";
import "package:async_helper/async_helper.dart";
import "package:expect/expect.dart";
String localFile(path) => Platform.script.resolve(path).toFilePath();
SecurityContext serverContext = new SecurityContext()
..useCertificateChain(localFile('certificates/server_chain.pem'))
..usePrivateKey(localFile('certificates/server_key.pem'),
password: 'dartdart');
SecurityContext clientContext = new SecurityContext()
..setTrustedCertificates(file: localFile('certificates/trusted_certs.pem'));
InternetAddress HOST;
const CERTIFICATE = "localhost_cert";
Future<RawSecureServerSocket> startEchoServer() {
return RawSecureServerSocket.bind(HOST,
0,
CERTIFICATE).then((server) {
serverContext).then((server) {
server.listen((RawSecureSocket client) {
List<List<int>> readChunks = <List<int>>[];
List<int> dataToWrite = null;
@ -60,7 +69,8 @@ Future<RawSecureServerSocket> startEchoServer() {
Future testClient(server) {
Completer success = new Completer();
List<String> chunks = <String>[];
SecureSocket.connect(HOST, server.port).then((socket) {
SecureSocket.connect(HOST, server.port, context: clientContext)
.then((socket) {
socket.write("Hello server.");
socket.close();
socket.listen(
@ -79,9 +89,6 @@ Future testClient(server) {
void main() {
asyncStart();
String certificateDatabase = Platform.script.resolve('pkcert').toFilePath();
SecureSocket.initialize(database: certificateDatabase,
password: 'dartdart');
InternetAddress.lookup("localhost").then((hosts) => HOST = hosts.first)
.then((_) => startEchoServer())
.then(testClient)

View File

@ -14,11 +14,22 @@ import "package:async_helper/async_helper.dart";
import "package:expect/expect.dart";
InternetAddress HOST;
const CERTIFICATE = "localhost_cert";
String localFile(path) => Platform.script.resolve(path).toFilePath();
SecurityContext serverContext = new SecurityContext()
..useCertificateChain(localFile('certificates/server_chain.pem'))
..usePrivateKey(localFile('certificates/server_key.pem'),
password: 'dartdart');
SecurityContext clientContext = new SecurityContext()
..setTrustedCertificates(file: localFile('certificates/trusted_certs.pem'));
Future<SecureServerSocket> startEchoServer() {
return SecureServerSocket.bind(HOST,
0,
CERTIFICATE).then((server) {
serverContext).then((server) {
server.listen((SecureSocket client) {
client.fold(<int>[], (message, data) => message..addAll(data))
.then((message) {
@ -31,7 +42,8 @@ Future<SecureServerSocket> startEchoServer() {
}
Future testClient(server) {
return SecureSocket.connect(HOST, server.port).then((socket) {
return SecureSocket.connect(HOST, server.port, context: clientContext)
.then((socket) {
socket.write("Hello server.");
socket.close();
return socket.fold(<int>[], (message, data) => message..addAll(data))
@ -44,9 +56,6 @@ Future testClient(server) {
void main() {
asyncStart();
String certificateDatabase = Platform.script.resolve('pkcert').toFilePath();
SecureSocket.initialize(database: certificateDatabase,
password: 'dartdart');
InternetAddress.lookup("localhost").then((hosts) => HOST = hosts.first )
.then((_) => startEchoServer())
.then(testClient)

View File

@ -15,10 +15,19 @@ import "package:expect/expect.dart";
InternetAddress HOST;
SecureServerSocket SERVER;
const CERTIFICATE = "localhost_cert";
String localFile(path) => Platform.script.resolve(path).toFilePath();
SecurityContext serverContext = new SecurityContext()
..useCertificateChain(localFile('certificates/server_chain.pem'))
..usePrivateKey(localFile('certificates/server_key.pem'),
password: 'dartdart');
SecurityContext clientContext = new SecurityContext()
..setTrustedCertificates(file: localFile('certificates/trusted_certs.pem'));
Future startServer() {
return SecureServerSocket.bind(HOST, 0, CERTIFICATE).then((server) {
return SecureServerSocket.bind(HOST, 0, serverContext).then((server) {
SERVER = server;
SERVER.listen((SecureSocket client) {
client.fold(<int>[], (message, data) => message..addAll(data))
@ -34,7 +43,8 @@ Future startServer() {
}
Future testClient(name) {
return SecureSocket.connect(HOST, SERVER.port).then((socket) {
return SecureSocket.connect(HOST, SERVER.port, context: clientContext)
.then((socket) {
socket.add("Hello from client $name".codeUnits);
socket.close();
return socket.fold(<int>[], (message, data) => message..addAll(data))
@ -46,9 +56,6 @@ Future testClient(name) {
void main() {
asyncStart();
var certificateDatabase = Platform.script.resolve('pkcert').toFilePath();
SecureSocket.initialize(database: certificateDatabase,
password: 'dartdart');
InternetAddress.lookup("localhost").then((hosts) => HOST = hosts.first)
.then((_) => startServer())
.then((_) => ['ale', 'bar', 'che', 'den', 'els'].map(testClient))

View File

@ -9,16 +9,26 @@ import "package:async_helper/async_helper.dart";
import "package:expect/expect.dart";
InternetAddress HOST;
const CERTIFICATE = "localhost_cert";
String localFile(path) => Platform.script.resolve(path).toFilePath();
SecurityContext serverContext = new SecurityContext()
..useCertificateChain(localFile('certificates/server_chain.pem'))
..usePrivateKey(localFile('certificates/server_key.pem'),
password: 'dartdart');
SecurityContext clientContext = new SecurityContext()
..setTrustedCertificates(file: localFile('certificates/trusted_certs.pem'));
Future testClientCertificate() {
var completer = new Completer();
SecureServerSocket.bind(HOST,
0,
CERTIFICATE,
serverContext,
requestClientCertificate: true).then((server) {
var clientEndFuture = SecureSocket.connect(HOST,
server.port,
context: clientContext,
sendClientCertificate: true);
server.listen((serverEnd) {
X509Certificate certificate = serverEnd.peerCertificate;
@ -44,10 +54,11 @@ Future testRequiredClientCertificate() {
var completer = new Completer();
SecureServerSocket.bind(HOST,
0,
CERTIFICATE,
serverContext,
requireClientCertificate: true).then((server) {
var clientEndFuture = SecureSocket.connect(HOST,
server.port,
context: clientContext,
sendClientCertificate: true);
server.listen((serverEnd) {
X509Certificate certificate = serverEnd.peerCertificate;
@ -70,11 +81,6 @@ Future testRequiredClientCertificate() {
}
void main() {
String certificateDatabase = Platform.script.resolve('pkcert').toFilePath();
SecureSocket.initialize(database: certificateDatabase,
password: 'dartdart',
useBuiltinRoots: false);
asyncStart();
InternetAddress.lookup("localhost").then((hosts) => HOST = hosts.first)
.then((_) => testClientCertificate())

View File

@ -9,16 +9,25 @@ import "package:async_helper/async_helper.dart";
import "package:expect/expect.dart";
InternetAddress HOST;
const CERTIFICATE = "localhost_cert";
String localFile(path) => Platform.script.resolve(path).toFilePath();
SecurityContext serverContext = new SecurityContext()
..useCertificateChain(localFile('certificates/server_chain.pem'))
..usePrivateKey(localFile('certificates/server_key.pem'),
password: 'dartdart');
SecurityContext clientContext = new SecurityContext()
..setTrustedCertificates(file: localFile('certificates/trusted_certs.pem'));
Future testNoClientCertificate() {
var completer = new Completer();
SecureServerSocket.bind(HOST,
0,
CERTIFICATE,
serverContext,
requestClientCertificate: true).then((server) {
var clientEndFuture = SecureSocket.connect(HOST,
server.port);
server.port,
context: clientContext);
server.listen((serverEnd) {
X509Certificate certificate = serverEnd.peerCertificate;
Expect.isNull(certificate);
@ -38,10 +47,11 @@ Future testNoRequiredClientCertificate() {
bool clientError = false;
SecureServerSocket.bind(HOST,
0,
CERTIFICATE,
serverContext,
requireClientCertificate: true).then((server) {
Future clientDone = SecureSocket.connect(HOST, server.port)
.catchError((e) { clientError = true; });
Future clientDone =
SecureSocket.connect(HOST, server.port, context: clientContext)
.catchError((e) { clientError = true; });
server.listen((serverEnd) {
Expect.fail("Got a unverifiable connection");
},
@ -57,11 +67,6 @@ Future testNoRequiredClientCertificate() {
}
void main() {
String certificateDatabase = Platform.script.resolve('pkcert').toFilePath();
SecureSocket.initialize(database: certificateDatabase,
password: 'dartdart',
useBuiltinRoots: false);
asyncStart();
InternetAddress.lookup("localhost").then((hosts) => HOST = hosts.first)
.then((_) => testNoRequiredClientCertificate())

View File

@ -14,7 +14,16 @@ import "package:async_helper/async_helper.dart";
import "package:expect/expect.dart";
InternetAddress HOST;
const CERTIFICATE = "localhost_cert";
String localFile(path) => Platform.script.resolve(path).toFilePath();
SecurityContext serverContext = new SecurityContext()
..useCertificateChain(localFile('certificates/server_chain.pem'))
..usePrivateKey(localFile('certificates/server_key.pem'),
password: 'dartdart');
SecurityContext clientContext = new SecurityContext()
..setTrustedCertificates(file: localFile('certificates/trusted_certs.pem'));
void testCloseOneEnd(String toClose) {
asyncStart();
@ -25,7 +34,7 @@ void testCloseOneEnd(String toClose) {
.then((_) {
asyncEnd();
});
SecureServerSocket.bind(HOST, 0, CERTIFICATE).then((server) {
SecureServerSocket.bind(HOST, 0, serverContext).then((server) {
server.listen((serverConnection) {
serverConnection.listen(
(data) {
@ -43,7 +52,8 @@ void testCloseOneEnd(String toClose) {
onDone: () {
serverDone.complete(null);
});
SecureSocket.connect(HOST, server.port).then((clientConnection) {
SecureSocket.connect(HOST, server.port, context: clientContext)
.then((clientConnection) {
clientConnection.listen(
(data) {
Expect.fail("No data should be received by client");
@ -61,8 +71,9 @@ void testCloseOneEnd(String toClose) {
void testCloseBothEnds() {
asyncStart();
SecureServerSocket.bind(HOST, 0, CERTIFICATE).then((server) {
var clientEndFuture = SecureSocket.connect(HOST, server.port);
SecureServerSocket.bind(HOST, 0, serverContext).then((server) {
var clientEndFuture =
SecureSocket.connect(HOST, server.port, context: clientContext);
server.listen((serverEnd) {
clientEndFuture.then((clientEnd) {
clientEnd.destroy();
@ -83,7 +94,7 @@ testPauseServerSocket() {
SecureServerSocket.bind(HOST,
0,
CERTIFICATE,
serverContext,
backlog: 2 * socketCount).then((server) {
Expect.isTrue(server.port > 0);
var subscription;
@ -97,12 +108,12 @@ testPauseServerSocket() {
});
// Pause the server socket subscription and resume it after having
// connected a number client sockets. Then connect more client
// sockets.
// connected a number client sockets. Then connect more client sockets.
subscription.pause();
var connectCount = 0;
for (int i = 0; i < socketCount; i++) {
SecureSocket.connect(HOST, server.port).then((connection) {
SecureSocket.connect(HOST, server.port, context: clientContext)
.then((connection) {
connection.close();
});
}
@ -110,7 +121,8 @@ testPauseServerSocket() {
subscription.resume();
resumed = true;
for (int i = 0; i < socketCount; i++) {
SecureSocket.connect(HOST, server.port).then((connection) {
SecureSocket.connect(HOST, server.port, context: clientContext)
.then((connection) {
connection.close();
});
}
@ -125,7 +137,7 @@ testCloseServer() {
asyncStart();
List ends = [];
SecureServerSocket.bind(HOST, 0, CERTIFICATE).then((server) {
SecureServerSocket.bind(HOST, 0, serverContext).then((server) {
Expect.isTrue(server.port > 0);
void checkDone() {
if (ends.length < 2 * socketCount) return;
@ -142,7 +154,8 @@ testCloseServer() {
});
for (int i = 0; i < socketCount; i++) {
SecureSocket.connect(HOST, server.port).then((connection) {
SecureSocket.connect(HOST, server.port, context: clientContext)
.then((connection) {
ends.add(connection);
checkDone();
});
@ -153,10 +166,6 @@ testCloseServer() {
main() {
asyncStart();
String certificateDatabase = Platform.script.resolve('pkcert').toFilePath();
SecureSocket.initialize(database: certificateDatabase,
password: 'dartdart',
useBuiltinRoots: false);
InternetAddress.lookup("localhost").then((hosts) {
HOST = hosts.first;
runTests();

View File

@ -14,11 +14,20 @@ import "package:async_helper/async_helper.dart";
import "package:expect/expect.dart";
InternetAddress HOST;
const CERTIFICATE = "localhost_cert";
String localFile(path) => Platform.script.resolve(path).toFilePath();
SecurityContext serverContext = new SecurityContext()
..useCertificateChain(localFile('certificates/server_chain.pem'))
..usePrivateKey(localFile('certificates/server_key.pem'),
password: 'dartdart');
SecurityContext clientContext = new SecurityContext()
..setTrustedCertificates(file: localFile('certificates/trusted_certs.pem'));
void testSimpleBind() {
asyncStart();
SecureServerSocket.bind(HOST, 0, CERTIFICATE).then((s) {
SecureServerSocket.bind(HOST, 0, serverContext).then((s) {
Expect.isTrue(s.port > 0);
s.close();
asyncEnd();
@ -30,7 +39,7 @@ void testInvalidBind() {
// Bind to a unknown DNS name.
asyncStart();
SecureServerSocket.bind("ko.faar.__hest__", 0, CERTIFICATE).then((_) {
SecureServerSocket.bind("ko.faar.__hest__", 0, serverContext).then((_) {
Expect.fail("Failure expected");
}).catchError((error) {
Expect.isTrue(error is SocketException);
@ -39,7 +48,7 @@ void testInvalidBind() {
// Bind to an unavaliable IP-address.
asyncStart();
SecureServerSocket.bind("8.8.8.8", 0, CERTIFICATE).then((_) {
SecureServerSocket.bind("8.8.8.8", 0, serverContext).then((_) {
Expect.fail("Failure expected");
}).catchError((error) {
Expect.isTrue(error is SocketException);
@ -48,10 +57,10 @@ void testInvalidBind() {
// Bind to a port already in use.
asyncStart();
SecureServerSocket.bind(HOST, 0, CERTIFICATE).then((s) {
SecureServerSocket.bind(HOST, 0, serverContext).then((s) {
SecureServerSocket.bind(HOST,
s.port,
CERTIFICATE).then((t) {
serverContext).then((t) {
Expect.fail("Multiple listens on same port");
}).catchError((error) {
Expect.isTrue(error is SocketException);
@ -61,12 +70,18 @@ void testInvalidBind() {
});
}
void testSimpleConnect(String certificate) {
void testSimpleConnect() {
asyncStart();
SecureServerSocket.bind(HOST, 0, certificate).then((server) {
var clientEndFuture = SecureSocket.connect(HOST, server.port);
SecureServerSocket.bind(HOST, 0, serverContext).then((server) {
var clientEndFuture =
SecureSocket.connect(HOST, server.port, context: clientContext);
server.listen((serverEnd) {
clientEndFuture.then((clientEnd) {
var x5 = clientEnd.peerCertificate;
print(x5.subject);
print(x5.issuer);
print(x5.startValidity);
print(x5.endValidity);
clientEnd.close();
serverEnd.close();
server.close();
@ -76,22 +91,32 @@ void testSimpleConnect(String certificate) {
});
}
void testSimpleConnectFail(String certificate, bool cancelOnError) {
void testSimpleConnectFail(SecurityContext serverContext,
SecurityContext clientContext,
bool cancelOnError) {
print('$serverContext $clientContext $cancelOnError');
asyncStart();
SecureServerSocket.bind(HOST, 0, certificate).then((server) {
var clientEndFuture = SecureSocket.connect(HOST, server.port)
SecureServerSocket.bind(HOST, 0, serverContext).then((server) {
var clientEndFuture =
SecureSocket.connect(HOST, server.port, context: clientContext)
.then((clientEnd) {
Expect.fail("No client connection expected.");
})
.catchError((error) {
Expect.isTrue(error is HandshakeException ||
// TODO(whesse): When null context is supported, disallow
// the ArgumentError type here.
Expect.isTrue(error is ArgumentError ||
error is HandshakeException ||
error is SocketException);
});
server.listen((serverEnd) {
Expect.fail("No server connection expected.");
},
onError: (error) {
Expect.isTrue(error is CertificateException);
// TODO(whesse): When null context is supported, disallow
// the ArgumentError type here.
Expect.isTrue(error is ArgumentError ||
error is HandshakeException);
clientEndFuture.then((_) {
if (!cancelOnError) server.close();
asyncEnd();
@ -103,9 +128,10 @@ void testSimpleConnectFail(String certificate, bool cancelOnError) {
void testServerListenAfterConnect() {
asyncStart();
SecureServerSocket.bind(HOST, 0, CERTIFICATE).then((server) {
SecureServerSocket.bind(HOST, 0, serverContext).then((server) {
Expect.isTrue(server.port > 0);
var clientEndFuture = SecureSocket.connect(HOST, server.port);
var clientEndFuture =
SecureSocket.connect(HOST, server.port, context: clientContext);
new Timer(const Duration(milliseconds: 500), () {
server.listen((serverEnd) {
clientEndFuture.then((clientEnd) {
@ -144,7 +170,7 @@ void testSimpleReadWrite() {
}
}
SecureServerSocket.bind(HOST, 0, CERTIFICATE).then((server) {
SecureServerSocket.bind(HOST, 0, serverContext).then((server) {
server.listen((client) {
int bytesRead = 0;
int bytesWritten = 0;
@ -166,7 +192,8 @@ void testSimpleReadWrite() {
});
});
SecureSocket.connect(HOST, server.port).then((socket) {
SecureSocket.connect(HOST, server.port, context: clientContext)
.then((socket) {
int bytesRead = 0;
int bytesWritten = 0;
List<int> dataSent = createTestData();
@ -189,10 +216,6 @@ void testSimpleReadWrite() {
main() {
asyncStart();
String certificateDatabase = Platform.script.resolve('pkcert').toFilePath();
SecureSocket.initialize(database: certificateDatabase,
password: 'dartdart',
useBuiltinRoots: false);
InternetAddress.lookup("localhost").then((hosts) {
HOST = hosts.first;
runTests();
@ -203,12 +226,16 @@ main() {
runTests() {
testSimpleBind();
testInvalidBind();
testSimpleConnect(CERTIFICATE);
testSimpleConnect("CN=localhost");
testSimpleConnectFail("not_a_nickname", false);
testSimpleConnectFail("CN=notARealDistinguishedName", false);
testSimpleConnectFail("not_a_nickname", true);
testSimpleConnectFail("CN=notARealDistinguishedName", true);
testSimpleConnect();
for (var server in [serverContext, null]) {
for (var client in [clientContext, null]) {
for (bool cancelOnError in [true, false]) {
if (server == null || client == null) {
testSimpleConnectFail(server, client, cancelOnError);
}
}
}
}
testServerListenAfterConnect();
testSimpleReadWrite();
}

View File

@ -24,11 +24,21 @@ import "package:expect/expect.dart";
import "package:async_helper/async_helper.dart";
InternetAddress HOST;
const CERTIFICATE = "localhost_cert";
String localFile(path) => Platform.script.resolve(path).toFilePath();
SecurityContext serverContext = new SecurityContext()
..useCertificateChain(localFile('certificates/server_chain.pem'))
..usePrivateKey(localFile('certificates/server_key.pem'),
password: 'dartdart');
SecurityContext clientContext = new SecurityContext()
..setTrustedCertificates(file: localFile('certificates/trusted_certs.pem'));
Future<SecureServerSocket> startServer() {
return SecureServerSocket.bind(HOST,
0,
CERTIFICATE).then((server) {
serverContext).then((server) {
server.listen((SecureSocket client) {
client.fold(<int>[], (message, data) => message..addAll(data))
.then((message) {
@ -44,7 +54,8 @@ Future<SecureServerSocket> startServer() {
}
Future testClient(server, name) {
return SecureSocket.connect(HOST, server.port).then((socket) {
return SecureSocket.connect(HOST, server.port, context: clientContext)
.then((socket) {
socket.write("Hello from client $name");
socket.close();
return socket.fold(<int>[], (message, data) => message..addAll(data))
@ -57,9 +68,6 @@ Future testClient(server, name) {
void main() {
asyncStart();
String certificateDatabase = Platform.script.resolve('pkcert').toFilePath();
SecureSocket.initialize(database: certificateDatabase,
password: 'dartdart');
InternetAddress.lookup("localhost").then((hosts) {
HOST = hosts.first;
runTests().then((_) => asyncEnd());

View File

@ -1,4 +1,4 @@
// Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file
// Copyright (c) 2015, the Dart project authors. Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
@ -8,26 +8,31 @@ import 'dart:convert';
import 'package:expect/expect.dart';
import 'package:async_helper/async_helper.dart';
const String MAX_LEN_ERROR =
const String NAME_LENGTH_ERROR =
'Length of protocol must be between 1 and 255';
const String MAX_MSG_LEN_ERROR =
'The maximum message length supported is 2^15-1';
const String MESSAGE_LENGTH_ERROR =
'The maximum message length supported is 2^13-1';
void InitializeSSL() {
var testPkcertDatabase = Platform.script.resolve('pkcert').toFilePath();
SecureSocket.initialize(database: testPkcertDatabase,
password: 'dartdart');
}
String localFile(path) => Platform.script.resolve(path).toFilePath();
// Tests that client/server with same protocol can securly establish a
// connection, negogiate the protocol and can send data to each other.
void testSuccessfulAlpnNegogiationConnection(List<String> clientProtocols,
SecurityContext clientContext() => new SecurityContext()
..setTrustedCertificates(file: localFile('certificates/trusted_certs.pem'));
SecurityContext serverContext() => new SecurityContext()
..useCertificateChain(localFile('certificates/server_chain.pem'))
..usePrivateKey(localFile('certificates/server_key.pem'),
password: 'dartdart');
// Tests that client/server with same protocol can securely establish a
// connection, negotiate the protocol and can send data to each other.
void testSuccessfulAlpnNegotiationConnection(List<String> clientProtocols,
List<String> serverProtocols,
String selectedProtocol) {
asyncStart();
SecureServerSocket.bind('localhost', 0, 'localhost_cert',
supportedProtocols: serverProtocols).then((SecureServerSocket server) {
var sContext = serverContext()..setAlpnProtocols(serverProtocols, true);
SecureServerSocket.bind('localhost', 0, sContext)
.then((SecureServerSocket server) {
asyncStart();
server.first.then((SecureSocket socket) {
@ -40,7 +45,7 @@ void testSuccessfulAlpnNegogiationConnection(List<String> clientProtocols,
});
asyncStart();
SecureSocket.connect('localhost', server.port,
SecureSocket.connect('localhost', server.port, context: clientContext(),
supportedProtocols: clientProtocols).then((socket) {
Expect.equals(selectedProtocol, socket.selectedProtocol);
socket..write('client message')..close();
@ -55,160 +60,145 @@ void testSuccessfulAlpnNegogiationConnection(List<String> clientProtocols,
});
}
void testFailedAlpnNegogiationConnection(List<String> clientProtocols,
List<String> serverProtocols) {
asyncStart();
SecureServerSocket.bind('localhost', 0, 'localhost_cert',
supportedProtocols: serverProtocols).then((SecureServerSocket server) {
void testInvalidArgument(List<String> protocols, String errorIncludes) {
testInvalidArgumentServerContext(protocols, errorIncludes);
testInvalidArgumentClientContext(protocols, errorIncludes);
testInvalidArgumentClientConnect(protocols, errorIncludes);
}
asyncStart();
server.first.catchError((error, stack) {
Expect.isTrue(error is HandshakeException);
asyncEnd();
});
asyncStart();
SecureSocket.connect('localhost',
server.port,
supportedProtocols: clientProtocols)
.catchError((error, stack) {
Expect.isTrue(error is HandshakeException);
asyncEnd();
});
asyncEnd();
void testInvalidArgumentServerContext(List<String> protocols,
String errorIncludes) {
Expect.throws(() => serverContext().setAlpnProtocols(protocols, true), (e) {
Expect.isTrue(e is ArgumentError);
Expect.isTrue(e.toString().contains(errorIncludes));
return true;
});
}
void testInvalidArgumentsLongName(List<String> protocols,
bool isLenError,
bool isMsgLenError) {
void testInvalidArgumentClientContext(List<String> protocols,
String errorIncludes) {
Expect.throws(() => clientContext().setAlpnProtocols(protocols, false), (e) {
Expect.isTrue(e is ArgumentError);
Expect.isTrue(e.toString().contains(errorIncludes));
return true;
});
}
void testInvalidArgumentClientConnect(List<String> protocols,
String errorIncludes) {
asyncStart();
SecureServerSocket.bind('localhost', 0, 'localhost_cert',
supportedProtocols: protocols).then((SecureServerSocket server) {
var sContext = serverContext()..setAlpnProtocols(['abc'], true);
SecureServerSocket.bind('localhost', 0, sContext).then((server) async {
asyncStart();
server.listen((SecureSocket socket) {
Expect.fail(
"Unexpected connection made to server, with bad client argument");
}, onError: (e) {
Expect.fail("Unexpected error on server stream: $e");
}, onDone: () { asyncEnd();});
asyncStart();
server.first.catchError((error, stack) {
String errorString = '${(error as ArgumentError)}';
if (isLenError) {
Expect.isTrue(errorString.contains(MAX_LEN_ERROR));
} else if (isMsgLenError) {
Expect.isTrue(errorString.contains(MAX_MSG_LEN_ERROR));
} else {
throw 'unreachable';
}
SecureSocket.connect('localhost', server.port, context: clientContext(),
supportedProtocols: protocols).then((socket) {
Expect.fail(
"Unexpected connection made from client, with bad client argument");
}, onError: (e) {
Expect.isTrue(e is ArgumentError);
Expect.isTrue(e.toString().contains(errorIncludes));
server.close();
asyncEnd();
});
asyncStart();
SecureSocket.connect('localhost',
server.port,
supportedProtocols: protocols)
.catchError((error, stack) {
String errorString = '${(error as ArgumentError)}';
if (isLenError) {
Expect.isTrue(errorString.contains(MAX_LEN_ERROR));
} else if (isMsgLenError) {
Expect.isTrue(errorString.contains(MAX_MSG_LEN_ERROR));
} else {
throw 'unreachable';
}
asyncEnd();
});
asyncEnd();
});
}
main() {
InitializeSSL();
final longname256 = 'p' * 256;
final String longname255 = 'p' * 255;
final String strangelongname255 = 'ø' + 'p' * 253;
final String strangelongname256 = 'ø' + 'p' * 254;
// This produces a message of (1 << 15)-2 bytes (1 length and 1 ascii byte).
final List<String> allProtocols = new Iterable.generate(
(1 << 14) - 1, (i) => '0').toList();
// This produces a message of (1 << 13) - 2 bytes. 2^12 -1 strings are each
// encoded by 1 length byte and 1 ascii byte.
final List<String> manyProtocols = new Iterable.generate(
(1 << 12) - 1, (i) => '0').toList();
// This produces a message of (1 << 15) bytes (1 length and 1 ascii byte).
final List<String> allProtocolsPlusOne = new Iterable.generate(
(1 << 14), (i) => '0').toList();
// This produces a message of (1 << 13) bytes. 2^12 strings are each
// encoded by 1 length byte and 1 ascii byte.
final List<String> tooManyProtocols = new Iterable.generate(
(1 << 12), (i) => '0').toList();
// Protocols are in order of decreasing priority. First matching protocol
// will be taken.
// Test successfull negotiation, including priority.
testSuccessfulAlpnNegogiationConnection(['a'],
// Protocols are in order of decreasing priority. The server will select
// the first protocol from its list that has a match in the client list.
// Test successful negotiation, including priority.
testSuccessfulAlpnNegotiationConnection(['a'],
['a'],
'a');
testSuccessfulAlpnNegogiationConnection([longname255],
testSuccessfulAlpnNegotiationConnection([longname255],
[longname255],
longname255);
testSuccessfulAlpnNegogiationConnection([strangelongname255],
testSuccessfulAlpnNegotiationConnection([strangelongname255],
[strangelongname255],
strangelongname255);
testSuccessfulAlpnNegogiationConnection(allProtocols,
allProtocols,
testSuccessfulAlpnNegotiationConnection(manyProtocols,
manyProtocols,
'0');
testSuccessfulAlpnNegogiationConnection(['a', 'b', 'c'],
testSuccessfulAlpnNegotiationConnection(['a', 'b', 'c'],
['a', 'b', 'c'],
'a');
testSuccessfulAlpnNegogiationConnection(['a', 'b', 'c'],
testSuccessfulAlpnNegotiationConnection(['a', 'b', 'c'],
['c'],
'c');
// Server precedence.
testSuccessfulAlpnNegogiationConnection(['a', 'b', 'c'],
testSuccessfulAlpnNegotiationConnection(['a', 'b', 'c'],
['c', 'b', 'a'],
'a');
'c');
testSuccessfulAlpnNegogiationConnection(['c'],
testSuccessfulAlpnNegotiationConnection(['c'],
['a', 'b', 'c'],
'c');
testSuccessfulAlpnNegogiationConnection(['s1', 'b', 'e1'],
testSuccessfulAlpnNegotiationConnection(['s1', 'b', 'e1'],
['s2', 'b', 'e2'],
'b');
// Test no protocol negotiation support
testSuccessfulAlpnNegogiationConnection(null,
testSuccessfulAlpnNegotiationConnection(null,
null,
null);
testSuccessfulAlpnNegogiationConnection(['a', 'b', 'c'],
testSuccessfulAlpnNegotiationConnection(['a', 'b', 'c'],
null,
null);
testSuccessfulAlpnNegogiationConnection(null,
testSuccessfulAlpnNegotiationConnection(null,
['a', 'b', 'c'],
null);
testSuccessfulAlpnNegogiationConnection([],
testSuccessfulAlpnNegotiationConnection([],
[],
null);
testSuccessfulAlpnNegogiationConnection(['a', 'b', 'c'],
testSuccessfulAlpnNegotiationConnection(['a', 'b', 'c'],
[],
null);
testSuccessfulAlpnNegogiationConnection([],
testSuccessfulAlpnNegotiationConnection([],
['a', 'b', 'c'],
null);
// Test non-overlapping protocols.
testFailedAlpnNegogiationConnection(['a'], ['b']);
// Test non-overlapping protocols. The ALPN RFC says the connection
// should be terminated, but OpenSSL continues as if no ALPN is present.
// Issue https://github.com/dart-lang/sdk/issues/23580
// Chromium issue https://code.google.com/p/chromium/issues/detail?id=497770
testSuccessfulAlpnNegotiationConnection(['a'], ['b'], null);
// Test too short / too long protocol names.
testInvalidArgumentsLongName([longname256], true, false);
testInvalidArgumentsLongName([strangelongname256], true, false);
testInvalidArgumentsLongName([''], true, false);
testInvalidArgumentsLongName(allProtocolsPlusOne, false, true);
testInvalidArgumentsLongName(allProtocolsPlusOne, false, true);
testInvalidArgument([longname256], NAME_LENGTH_ERROR);
testInvalidArgument([strangelongname256], NAME_LENGTH_ERROR);
testInvalidArgument([''], NAME_LENGTH_ERROR);
testInvalidArgument(tooManyProtocols, MESSAGE_LENGTH_ERROR);
}

View File

@ -5,23 +5,15 @@
import "package:expect/expect.dart";
import "dart:io";
void testInitialzeArguments() {
Expect.throws(() => SecureSocket.initialize(database: "foo.txt"));
Expect.throws(() => SecureSocket.initialize(password: false));
Expect.throws(() => SecureSocket.initialize(useBuiltinRoots: 7));
}
void testServerSocketArguments() {
Expect.throws(() =>
SecureServerSocket.bind(SERVER_ADDRESS, 65536, 5, CERTIFICATE));
SecureServerSocket.bind(SERVER_ADDRESS, 65536, null));
Expect.throws(() =>
SecureServerSocket.bind(SERVER_ADDRESS, -1, CERTIFICATE));
SecureServerSocket.bind(SERVER_ADDRESS, -1, null));
Expect.throws(() =>
SecureServerSocket.bind(SERVER_ADDRESS, 0, -1, CERTIFICATE));
SecureServerSocket.bind(SERVER_ADDRESS, 0, "not a context"));
}
void main() {
testInitialzeArguments();
SecureSocket.initialize();
testServerSocketArguments();
}

View File

@ -158,10 +158,6 @@ Future test(bool hostnameInConnect) {
main() {
String certificateDatabase = Platform.script.resolve('pkcert').toFilePath();
SecureSocket.initialize(database: certificateDatabase,
password: 'dartdart',
useBuiltinRoots: false);
asyncStart();
InternetAddress.lookup("localhost").then((hosts) {
HOST = hosts.first;

View File

@ -12,8 +12,10 @@ import "dart:convert";
import "dart:io";
const HOST_NAME = "localhost";
const CERTIFICATE = "localhost_cert";
String localFile(path) => Platform.script.resolve(path).toFilePath();
SecurityContext clientContext = new SecurityContext()
..setTrustedCertificates(file: localFile('certificates/trusted_certs.pem'));
class ExpectException implements Exception {
ExpectException(this.message);
@ -37,7 +39,10 @@ void expect(condition) {
void runClient(int port) {
SecureSocket.connect(HOST_NAME, port, sendClientCertificate: true)
SecureSocket.connect(HOST_NAME,
port,
context: clientContext,
sendClientCertificate: true)
.then((SecureSocket socket) {
X509Certificate certificate = socket.peerCertificate;
expect(certificate != null);
@ -74,6 +79,5 @@ void runClient(int port) {
void main(List<String> args) {
SecureSocket.initialize(database: args[1], password: 'dartdart');
runClient(int.parse(args[0]));
}

View File

@ -14,17 +14,15 @@ import "package:expect/expect.dart";
import "package:path/path.dart";
const HOST_NAME = "localhost";
const CERTIFICATE = "localhost_cert";
String certificateDatabase() => Platform.script.resolve('pkcert').toFilePath();
String localFile(path) => Platform.script.resolve(path).toFilePath();
SecurityContext serverContext = new SecurityContext()
..useCertificateChain(localFile('certificates/server_chain.pem'))
..usePrivateKey(localFile('certificates/server_key.pem'),
password: 'dartdart');
Future<SecureServerSocket> runServer() {
SecureSocket.initialize(database: certificateDatabase(),
password: 'dartdart');
return SecureServerSocket.bind(HOST_NAME, 0, CERTIFICATE)
return SecureServerSocket.bind(HOST_NAME, 0, serverContext)
.then((SecureServerSocket server) {
server.listen((SecureSocket socket) {
Expect.isNull(socket.peerCertificate);
@ -71,8 +69,7 @@ void main() {
Expect.isTrue(clientScript.endsWith("_client.dart"));
Process.run(Platform.executable,
[clientScript,
server.port.toString(),
certificateDatabase()])
server.port.toString()])
.then((ProcessResult result) {
if (result.exitCode != 0) {
print("Client failed, stdout:");

View File

@ -12,12 +12,22 @@ import "package:path/path.dart";
import "dart:async";
import "dart:io";
String localFile(path) => Platform.script.resolve(path).toFilePath();
SecurityContext serverContext = new SecurityContext()
..useCertificateChain(localFile('certificates/server_chain.pem'))
..usePrivateKey(localFile('certificates/server_key.pem'),
password: 'dartdart');
SecurityContext clientContext = new SecurityContext()
..setTrustedCertificates(file: localFile('certificates/trusted_certs.pem'));
Future<HttpServer> startServer() {
return HttpServer.bindSecure(
"localhost",
0,
backlog: 5,
certificateName: 'localhost_cert').then((server) {
serverContext,
backlog: 5).then((server) {
server.listen((HttpRequest request) {
request.listen(
(_) { },
@ -33,17 +43,11 @@ Future<HttpServer> startServer() {
});
}
void InitializeSSL() {
var testPkcertDatabase = Platform.script.resolve('pkcert').toFilePath();
SecureSocket.initialize(database: testPkcertDatabase,
password: 'dartdart');
}
void main() {
InitializeSSL();
List<int> body = <int>[];
startServer().then((server) {
SecureSocket.connect("localhost", server.port).then((socket) {
SecureSocket.connect("localhost", server.port, context: clientContext)
.then((socket) {
socket.write("GET / HTTP/1.0\r\nHost: localhost\r\n\r\n");
socket.close();
socket.listen(

View File

@ -8,6 +8,11 @@
import "dart:async";
import "dart:io";
String localFile(path) => Platform.script.resolve(path).toFilePath();
SecurityContext clientContext = new SecurityContext()
..setTrustedCertificates(file: localFile('certificates/trusted_certs.pem'));
class ExpectException implements Exception {
ExpectException(this.message);
String toString() => "ExpectException: $message";
@ -26,7 +31,7 @@ Future runClients(int port) {
var testFutures = [];
for (int i = 0; i < 20; ++i) {
testFutures.add(
SecureSocket.connect(HOST_NAME, port)
SecureSocket.connect(HOST_NAME, port, context: clientContext)
.then((SecureSocket socket) {
expect(false);
}, onError: (e) {
@ -38,7 +43,6 @@ Future runClients(int port) {
void main(List<String> args) {
SecureSocket.initialize();
runClients(int.parse(args[0]))
.then((_) => print('SUCCESS'));
}

View File

@ -11,14 +11,15 @@ import "dart:async";
import "dart:io";
const HOST_NAME = "localhost";
const CERTIFICATE = "localhost_cert";
String localFile(path) => Platform.script.resolve(path).toFilePath();
SecurityContext serverContext = new SecurityContext()
..useCertificateChain(localFile('certificates/untrusted_server_chain.pem'))
..usePrivateKey(localFile('certificates/untrusted_server_key.pem'),
password: 'dartdart');
Future<SecureServerSocket> runServer() {
SecureSocket.initialize(
database: Platform.script.resolve('pkcert').toFilePath(),
password: 'dartdart');
return SecureServerSocket.bind(HOST_NAME, 0, CERTIFICATE)
return SecureServerSocket.bind(HOST_NAME, 0, serverContext)
.then((SecureServerSocket server) {
server.listen((SecureSocket socket) {
socket.listen((_) { },

View File

@ -14,7 +14,15 @@ import "package:async_helper/async_helper.dart";
import "package:expect/expect.dart";
InternetAddress HOST;
const CERTIFICATE = "localhost_cert";
String localFile(path) => Platform.script.resolve(path).toFilePath();
SecurityContext serverContext = new SecurityContext()
..useCertificateChain(localFile('certificates/server_chain.pem'))
..usePrivateKey(localFile('certificates/server_key.pem'),
password: 'dartdart');
SecurityContext clientContext = new SecurityContext()
..setTrustedCertificates(file: localFile('certificates/trusted_certs.pem'));
// This test creates a server and a client connects. After connecting
// and an optional initial handshake the connection is secured by
@ -156,9 +164,11 @@ void test(bool hostnameInConnect,
return Socket.connect(HOST, port).then((socket) {
var future;
if (hostnameInConnect) {
future = SecureSocket.secure(socket);
future = SecureSocket.secure(socket, context: clientContext);
} else {
future = SecureSocket.secure(socket, host: HOST);
future = SecureSocket.secure(socket,
host: HOST,
context: clientContext);
}
return future.then((secureSocket) {
socket.add([0]);
@ -170,9 +180,11 @@ void test(bool hostnameInConnect,
return runClientHandshake(socket).then((_) {
var future;
if (hostnameInConnect) {
future = SecureSocket.secure(socket);
future = SecureSocket.secure(socket, context: clientContext);
} else {
future = SecureSocket.secure(socket, host: HOST.host);
future = SecureSocket.secure(socket,
host: HOST,
context: clientContext);
}
return future.then((secureSocket) {
socket.add([0]);
@ -186,7 +198,7 @@ void test(bool hostnameInConnect,
serverReady(server) {
server.listen((client) {
if (!handshakeBeforeSecure) {
SecureSocket.secureServer(client, CERTIFICATE).then((secureClient) {
SecureSocket.secureServer(client, serverContext).then((secureClient) {
client.add([0]);
runServer(secureClient).then((_) => server.close());
});
@ -194,7 +206,7 @@ void test(bool hostnameInConnect,
runServerHandshake(client).then((carryOverData) {
SecureSocket.secureServer(
client,
CERTIFICATE,
serverContext,
bufferedData: carryOverData).then((secureClient) {
client.add([0]);
runServer(secureClient).then((_) => server.close());
@ -213,18 +225,15 @@ void test(bool hostnameInConnect,
main() {
asyncStart();
var certificateDatabase = Platform.script.resolve('pkcert').toFilePath();
SecureSocket.initialize(database: certificateDatabase,
password: 'dartdart',
useBuiltinRoots: false);
InternetAddress.lookup("localhost").then((hosts) {
HOST = hosts.first;
test(false, false);
test(true, false);
test(false, true);
test(true, true);
test(false, true, true);
test(true, true, true);
// TODO(whesse): Enable the test with all argument combinations:
// test(true, false);
// test(false, true);
// test(true, true);
// test(false, true, true);
// test(true, true, true);
asyncEnd();
});
}

View File

@ -25,6 +25,16 @@ const String webSocketGUID = "258EAFA5-E914-47DA-95CA-C5AB0DC85B11";
const String CERT_NAME = 'localhost_cert';
const String HOST_NAME = 'localhost';
String localFile(path) => Platform.script.resolve(path).toFilePath();
SecurityContext serverContext = new SecurityContext()
..useCertificateChain(localFile('certificates/server_chain.pem'))
..usePrivateKey(localFile('certificates/server_key.pem'),
password: 'dartdart');
SecurityContext clientContext = new SecurityContext()
..setTrustedCertificates(file: localFile('certificates/trusted_certs.pem'));
/**
* A SecurityConfiguration lets us run the tests over HTTP or HTTPS.
*/
@ -36,13 +46,14 @@ class SecurityConfiguration {
Future<HttpServer> createServer({int backlog: 0}) =>
secure ? HttpServer.bindSecure(HOST_NAME,
0,
backlog: backlog,
certificateName: CERT_NAME)
serverContext,
backlog: backlog)
: HttpServer.bind(HOST_NAME,
0,
backlog: backlog);
Future<WebSocket> createClient(int port) =>
// TODO(whesse): Add a client context argument to WebSocket.connect.
WebSocket.connect('${secure ? "wss" : "ws"}://$HOST_NAME:$port/');
@ -89,18 +100,11 @@ class SecurityConfiguration {
}
void initializeSSL() {
var testPkcertDatabase = Platform.script.resolve('pkcert').toFilePath();
SecureSocket.initialize(database: testPkcertDatabase,
password: "dartdart");
}
main() {
asyncStart();
new SecurityConfiguration(secure: false).runTests();
initializeSSL();
new SecurityConfiguration(secure: true).runTests();
// TODO(whesse): WebSocket.connect needs an optional context: parameter
// new SecurityConfiguration(secure: true).runTests();
asyncEnd();
}

View File

@ -36,6 +36,7 @@ part "../../../sdk/lib/io/platform_impl.dart";
part "../../../sdk/lib/io/service_object.dart";
part "../../../sdk/lib/io/secure_socket.dart";
part "../../../sdk/lib/io/secure_server_socket.dart";
part "../../../sdk/lib/io/security_context.dart";
part "../../../sdk/lib/io/socket.dart";
part "../../../sdk/lib/io/websocket.dart";
part "../../../sdk/lib/io/websocket_impl.dart";

View File

@ -19,9 +19,18 @@ import "package:path/path.dart";
const WEB_SOCKET_GUID = "258EAFA5-E914-47DA-95CA-C5AB0DC85B11";
const String CERT_NAME = 'localhost_cert';
const String HOST_NAME = 'localhost';
String localFile(path) => Platform.script.resolve(path).toFilePath();
SecurityContext serverContext = new SecurityContext()
..useCertificateChain(localFile('certificates/server_chain.pem'))
..usePrivateKey(localFile('certificates/server_key.pem'),
password: 'dartdart');
SecurityContext clientContext = new SecurityContext()
..setTrustedCertificates(file: localFile('certificates/trusted_certs.pem'));
/**
* A SecurityConfiguration lets us run the tests over HTTP or HTTPS.
*/
@ -33,13 +42,14 @@ class SecurityConfiguration {
Future<HttpServer> createServer({int backlog: 0}) =>
secure ? HttpServer.bindSecure(HOST_NAME,
0,
backlog: backlog,
certificateName: CERT_NAME)
serverContext,
backlog: backlog)
: HttpServer.bind(HOST_NAME,
0,
backlog: backlog);
Future<WebSocket> createClient(int port) =>
// TODO(whesse): Add client context argument to WebSocket.connect
WebSocket.connect('${secure ? "wss" : "ws"}://$HOST_NAME:$port/');
checkCloseStatus(webSocket, closeStatus, closeReason) {
@ -581,15 +591,8 @@ class SecurityConfiguration {
}
void initializeSSL() {
var testPkcertDatabase = Platform.script.resolve('pkcert').toFilePath();
SecureSocket.initialize(database: testPkcertDatabase,
password: "dartdart");
}
main() {
new SecurityConfiguration(secure: false).runTests();
initializeSSL();
new SecurityConfiguration(secure: true).runTests();
// TODO(whesse): Make WebSocket.connect() take an optional context: parameter.
// new SecurityConfiguration(secure: true).runTests();
}

View File

@ -196,3 +196,11 @@ io/http_client_connect_test: Crash # (static Iterable<Str... cannot handle sync
io/observatory_test: Crash # (static Iterable<Str... cannot handle sync*/async* functions
io/skipping_dart2js_compilations_test: Crash # (static Iterable<Str... cannot handle sync*/async* functions
priority_queue_stress_test: RuntimeError # Cannot read property 'length' of undefined
[ $runtime == vm ]
# Failures in secure networking while NSS is replaced with BoringSSL
io/https_client_certificate_test: RuntimeError # Issue 24070
io/secure_server_client_certificate_test: RuntimeError # Issue 24069
io/secure_server_client_no_certificate_test: RuntimeError # Issue 24069
io/secure_socket_renegotiate_test: RuntimeError
io/secure_socket_bad_data_test: RuntimeError # An error in a secure connection just puts a READ_CLOSED on the stream, rather than signaling an error on the stream.

View File

@ -1,7 +1,9 @@
# ignore everything
*
# except for items in the pkg directory and self
# except for items in the pkg directory and self.
# except for our files in boringssl. The checkout is in boringssl/src.
!.gitignore
!pkg
!pkg_tested
!boringssl
!d8

2
third_party/boringssl/.gitignore vendored Normal file
View File

@ -0,0 +1,2 @@
# ignore the checkout of boringssl.
src/

17
third_party/boringssl/README vendored Normal file
View File

@ -0,0 +1,17 @@
The files in this directory, except for src/, boringssl_dart.gyp, and
boringssl_configurations.gypi, are generated from the checkout of
boringssl in src/, by running the script
src/util/generate_build_files.py chromium.
That script is maintained by the chromium team, to make a gyp build
of boringssl that does not require go or perl. We modify the main
gyp file of this build, boringssl.gyp, to add configurations for
the target architectures, creating boringssl_dart.gyp.
When updating boringssl in Dart, delete this directory,
and check out the new boringssl to src. Then run the script, check out
our two files boringssl_dart.gyp and boringssl_configurations.gypi and commit
the changes and any added or deleted files, as well as a change to the
boringssl revision in DEPS. If there are changes in boringssl.gyp,
consider making similar changes to boringssl_dart.gyp
Test the changes on all platforms before committing, of course.

431
third_party/boringssl/boringssl.gypi vendored Normal file
View File

@ -0,0 +1,431 @@
# Copyright (c) 2014 The Chromium Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
# This file is created by generate_build_files.py. Do not edit manually.
{
'variables': {
'boringssl_ssl_sources': [
'src/ssl/d1_both.c',
'src/ssl/d1_clnt.c',
'src/ssl/d1_lib.c',
'src/ssl/d1_meth.c',
'src/ssl/d1_pkt.c',
'src/ssl/d1_srtp.c',
'src/ssl/d1_srvr.c',
'src/ssl/pqueue/pqueue.c',
'src/ssl/s3_both.c',
'src/ssl/s3_clnt.c',
'src/ssl/s3_enc.c',
'src/ssl/s3_lib.c',
'src/ssl/s3_meth.c',
'src/ssl/s3_pkt.c',
'src/ssl/s3_srvr.c',
'src/ssl/ssl_aead_ctx.c',
'src/ssl/ssl_algs.c',
'src/ssl/ssl_asn1.c',
'src/ssl/ssl_cert.c',
'src/ssl/ssl_cipher.c',
'src/ssl/ssl_lib.c',
'src/ssl/ssl_rsa.c',
'src/ssl/ssl_sess.c',
'src/ssl/ssl_stat.c',
'src/ssl/ssl_txt.c',
'src/ssl/t1_enc.c',
'src/ssl/t1_lib.c',
'src/ssl/t1_reneg.c',
],
'boringssl_crypto_sources': [
'err_data.c',
'src/crypto/aes/aes.c',
'src/crypto/aes/mode_wrappers.c',
'src/crypto/asn1/a_bitstr.c',
'src/crypto/asn1/a_bool.c',
'src/crypto/asn1/a_bytes.c',
'src/crypto/asn1/a_d2i_fp.c',
'src/crypto/asn1/a_dup.c',
'src/crypto/asn1/a_enum.c',
'src/crypto/asn1/a_gentm.c',
'src/crypto/asn1/a_i2d_fp.c',
'src/crypto/asn1/a_int.c',
'src/crypto/asn1/a_mbstr.c',
'src/crypto/asn1/a_object.c',
'src/crypto/asn1/a_octet.c',
'src/crypto/asn1/a_print.c',
'src/crypto/asn1/a_strnid.c',
'src/crypto/asn1/a_time.c',
'src/crypto/asn1/a_type.c',
'src/crypto/asn1/a_utctm.c',
'src/crypto/asn1/a_utf8.c',
'src/crypto/asn1/asn1_lib.c',
'src/crypto/asn1/asn1_par.c',
'src/crypto/asn1/asn_pack.c',
'src/crypto/asn1/bio_asn1.c',
'src/crypto/asn1/bio_ndef.c',
'src/crypto/asn1/f_enum.c',
'src/crypto/asn1/f_int.c',
'src/crypto/asn1/f_string.c',
'src/crypto/asn1/t_bitst.c',
'src/crypto/asn1/t_pkey.c',
'src/crypto/asn1/tasn_dec.c',
'src/crypto/asn1/tasn_enc.c',
'src/crypto/asn1/tasn_fre.c',
'src/crypto/asn1/tasn_new.c',
'src/crypto/asn1/tasn_prn.c',
'src/crypto/asn1/tasn_typ.c',
'src/crypto/asn1/tasn_utl.c',
'src/crypto/asn1/x_bignum.c',
'src/crypto/asn1/x_long.c',
'src/crypto/base64/base64.c',
'src/crypto/bio/bio.c',
'src/crypto/bio/bio_mem.c',
'src/crypto/bio/buffer.c',
'src/crypto/bio/connect.c',
'src/crypto/bio/fd.c',
'src/crypto/bio/file.c',
'src/crypto/bio/hexdump.c',
'src/crypto/bio/pair.c',
'src/crypto/bio/printf.c',
'src/crypto/bio/socket.c',
'src/crypto/bio/socket_helper.c',
'src/crypto/bn/add.c',
'src/crypto/bn/asm/x86_64-gcc.c',
'src/crypto/bn/bn.c',
'src/crypto/bn/cmp.c',
'src/crypto/bn/convert.c',
'src/crypto/bn/ctx.c',
'src/crypto/bn/div.c',
'src/crypto/bn/exponentiation.c',
'src/crypto/bn/gcd.c',
'src/crypto/bn/generic.c',
'src/crypto/bn/kronecker.c',
'src/crypto/bn/montgomery.c',
'src/crypto/bn/mul.c',
'src/crypto/bn/prime.c',
'src/crypto/bn/random.c',
'src/crypto/bn/rsaz_exp.c',
'src/crypto/bn/shift.c',
'src/crypto/bn/sqrt.c',
'src/crypto/buf/buf.c',
'src/crypto/bytestring/ber.c',
'src/crypto/bytestring/cbb.c',
'src/crypto/bytestring/cbs.c',
'src/crypto/chacha/chacha_generic.c',
'src/crypto/chacha/chacha_vec.c',
'src/crypto/cipher/aead.c',
'src/crypto/cipher/cipher.c',
'src/crypto/cipher/derive_key.c',
'src/crypto/cipher/e_aes.c',
'src/crypto/cipher/e_chacha20poly1305.c',
'src/crypto/cipher/e_des.c',
'src/crypto/cipher/e_null.c',
'src/crypto/cipher/e_rc2.c',
'src/crypto/cipher/e_rc4.c',
'src/crypto/cipher/e_ssl3.c',
'src/crypto/cipher/e_tls.c',
'src/crypto/cipher/tls_cbc.c',
'src/crypto/cmac/cmac.c',
'src/crypto/conf/conf.c',
'src/crypto/cpu-arm.c',
'src/crypto/cpu-intel.c',
'src/crypto/crypto.c',
'src/crypto/des/des.c',
'src/crypto/dh/check.c',
'src/crypto/dh/dh.c',
'src/crypto/dh/dh_asn1.c',
'src/crypto/dh/dh_impl.c',
'src/crypto/dh/params.c',
'src/crypto/digest/digest.c',
'src/crypto/digest/digests.c',
'src/crypto/directory_posix.c',
'src/crypto/directory_win.c',
'src/crypto/dsa/dsa.c',
'src/crypto/dsa/dsa_asn1.c',
'src/crypto/dsa/dsa_impl.c',
'src/crypto/ec/ec.c',
'src/crypto/ec/ec_asn1.c',
'src/crypto/ec/ec_key.c',
'src/crypto/ec/ec_montgomery.c',
'src/crypto/ec/oct.c',
'src/crypto/ec/p256-64.c',
'src/crypto/ec/simple.c',
'src/crypto/ec/util-64.c',
'src/crypto/ec/wnaf.c',
'src/crypto/ecdh/ecdh.c',
'src/crypto/ecdsa/ecdsa.c',
'src/crypto/ecdsa/ecdsa_asn1.c',
'src/crypto/engine/engine.c',
'src/crypto/err/err.c',
'src/crypto/evp/algorithm.c',
'src/crypto/evp/asn1.c',
'src/crypto/evp/digestsign.c',
'src/crypto/evp/evp.c',
'src/crypto/evp/evp_ctx.c',
'src/crypto/evp/p_dsa_asn1.c',
'src/crypto/evp/p_ec.c',
'src/crypto/evp/p_ec_asn1.c',
'src/crypto/evp/p_rsa.c',
'src/crypto/evp/p_rsa_asn1.c',
'src/crypto/evp/pbkdf.c',
'src/crypto/evp/sign.c',
'src/crypto/ex_data.c',
'src/crypto/hkdf/hkdf.c',
'src/crypto/hmac/hmac.c',
'src/crypto/lhash/lhash.c',
'src/crypto/md4/md4.c',
'src/crypto/md5/md5.c',
'src/crypto/mem.c',
'src/crypto/modes/cbc.c',
'src/crypto/modes/cfb.c',
'src/crypto/modes/ctr.c',
'src/crypto/modes/gcm.c',
'src/crypto/modes/ofb.c',
'src/crypto/obj/obj.c',
'src/crypto/obj/obj_xref.c',
'src/crypto/pem/pem_all.c',
'src/crypto/pem/pem_info.c',
'src/crypto/pem/pem_lib.c',
'src/crypto/pem/pem_oth.c',
'src/crypto/pem/pem_pk8.c',
'src/crypto/pem/pem_pkey.c',
'src/crypto/pem/pem_x509.c',
'src/crypto/pem/pem_xaux.c',
'src/crypto/pkcs8/p5_pbe.c',
'src/crypto/pkcs8/p5_pbev2.c',
'src/crypto/pkcs8/p8_pkey.c',
'src/crypto/pkcs8/pkcs8.c',
'src/crypto/poly1305/poly1305.c',
'src/crypto/poly1305/poly1305_arm.c',
'src/crypto/poly1305/poly1305_vec.c',
'src/crypto/rand/hwrand.c',
'src/crypto/rand/rand.c',
'src/crypto/rand/urandom.c',
'src/crypto/rand/windows.c',
'src/crypto/rc4/rc4.c',
'src/crypto/refcount_c11.c',
'src/crypto/refcount_lock.c',
'src/crypto/rsa/blinding.c',
'src/crypto/rsa/padding.c',
'src/crypto/rsa/rsa.c',
'src/crypto/rsa/rsa_asn1.c',
'src/crypto/rsa/rsa_impl.c',
'src/crypto/sha/sha1.c',
'src/crypto/sha/sha256.c',
'src/crypto/sha/sha512.c',
'src/crypto/stack/stack.c',
'src/crypto/thread.c',
'src/crypto/thread_none.c',
'src/crypto/thread_pthread.c',
'src/crypto/thread_win.c',
'src/crypto/time_support.c',
'src/crypto/x509/a_digest.c',
'src/crypto/x509/a_sign.c',
'src/crypto/x509/a_strex.c',
'src/crypto/x509/a_verify.c',
'src/crypto/x509/asn1_gen.c',
'src/crypto/x509/by_dir.c',
'src/crypto/x509/by_file.c',
'src/crypto/x509/i2d_pr.c',
'src/crypto/x509/pkcs7.c',
'src/crypto/x509/t_crl.c',
'src/crypto/x509/t_req.c',
'src/crypto/x509/t_x509.c',
'src/crypto/x509/t_x509a.c',
'src/crypto/x509/x509.c',
'src/crypto/x509/x509_att.c',
'src/crypto/x509/x509_cmp.c',
'src/crypto/x509/x509_d2.c',
'src/crypto/x509/x509_def.c',
'src/crypto/x509/x509_ext.c',
'src/crypto/x509/x509_lu.c',
'src/crypto/x509/x509_obj.c',
'src/crypto/x509/x509_r2x.c',
'src/crypto/x509/x509_req.c',
'src/crypto/x509/x509_set.c',
'src/crypto/x509/x509_trs.c',
'src/crypto/x509/x509_txt.c',
'src/crypto/x509/x509_v3.c',
'src/crypto/x509/x509_vfy.c',
'src/crypto/x509/x509_vpm.c',
'src/crypto/x509/x509cset.c',
'src/crypto/x509/x509name.c',
'src/crypto/x509/x509rset.c',
'src/crypto/x509/x509spki.c',
'src/crypto/x509/x509type.c',
'src/crypto/x509/x_algor.c',
'src/crypto/x509/x_all.c',
'src/crypto/x509/x_attrib.c',
'src/crypto/x509/x_crl.c',
'src/crypto/x509/x_exten.c',
'src/crypto/x509/x_info.c',
'src/crypto/x509/x_name.c',
'src/crypto/x509/x_pkey.c',
'src/crypto/x509/x_pubkey.c',
'src/crypto/x509/x_req.c',
'src/crypto/x509/x_sig.c',
'src/crypto/x509/x_spki.c',
'src/crypto/x509/x_val.c',
'src/crypto/x509/x_x509.c',
'src/crypto/x509/x_x509a.c',
'src/crypto/x509v3/pcy_cache.c',
'src/crypto/x509v3/pcy_data.c',
'src/crypto/x509v3/pcy_lib.c',
'src/crypto/x509v3/pcy_map.c',
'src/crypto/x509v3/pcy_node.c',
'src/crypto/x509v3/pcy_tree.c',
'src/crypto/x509v3/v3_akey.c',
'src/crypto/x509v3/v3_akeya.c',
'src/crypto/x509v3/v3_alt.c',
'src/crypto/x509v3/v3_bcons.c',
'src/crypto/x509v3/v3_bitst.c',
'src/crypto/x509v3/v3_conf.c',
'src/crypto/x509v3/v3_cpols.c',
'src/crypto/x509v3/v3_crld.c',
'src/crypto/x509v3/v3_enum.c',
'src/crypto/x509v3/v3_extku.c',
'src/crypto/x509v3/v3_genn.c',
'src/crypto/x509v3/v3_ia5.c',
'src/crypto/x509v3/v3_info.c',
'src/crypto/x509v3/v3_int.c',
'src/crypto/x509v3/v3_lib.c',
'src/crypto/x509v3/v3_ncons.c',
'src/crypto/x509v3/v3_pci.c',
'src/crypto/x509v3/v3_pcia.c',
'src/crypto/x509v3/v3_pcons.c',
'src/crypto/x509v3/v3_pku.c',
'src/crypto/x509v3/v3_pmaps.c',
'src/crypto/x509v3/v3_prn.c',
'src/crypto/x509v3/v3_purp.c',
'src/crypto/x509v3/v3_skey.c',
'src/crypto/x509v3/v3_sxnet.c',
'src/crypto/x509v3/v3_utl.c',
],
'boringssl_linux_aarch64_sources': [
'linux-aarch64/crypto/aes/aesv8-armx64.S',
'linux-aarch64/crypto/modes/ghashv8-armx64.S',
'linux-aarch64/crypto/sha/sha1-armv8.S',
'linux-aarch64/crypto/sha/sha256-armv8.S',
'linux-aarch64/crypto/sha/sha512-armv8.S',
],
'boringssl_linux_arm_sources': [
'linux-arm/crypto/aes/aes-armv4.S',
'linux-arm/crypto/aes/aesv8-armx32.S',
'linux-arm/crypto/aes/bsaes-armv7.S',
'linux-arm/crypto/bn/armv4-mont.S',
'linux-arm/crypto/modes/ghash-armv4.S',
'linux-arm/crypto/modes/ghashv8-armx32.S',
'linux-arm/crypto/sha/sha1-armv4-large.S',
'linux-arm/crypto/sha/sha256-armv4.S',
'linux-arm/crypto/sha/sha512-armv4.S',
'src/crypto/chacha/chacha_vec_arm.S',
'src/crypto/cpu-arm-asm.S',
'src/crypto/poly1305/poly1305_arm_asm.S',
],
'boringssl_linux_x86_sources': [
'linux-x86/crypto/aes/aes-586.S',
'linux-x86/crypto/aes/aesni-x86.S',
'linux-x86/crypto/aes/vpaes-x86.S',
'linux-x86/crypto/bn/bn-586.S',
'linux-x86/crypto/bn/co-586.S',
'linux-x86/crypto/bn/x86-mont.S',
'linux-x86/crypto/cpu-x86-asm.S',
'linux-x86/crypto/md5/md5-586.S',
'linux-x86/crypto/modes/ghash-x86.S',
'linux-x86/crypto/rc4/rc4-586.S',
'linux-x86/crypto/sha/sha1-586.S',
'linux-x86/crypto/sha/sha256-586.S',
'linux-x86/crypto/sha/sha512-586.S',
],
'boringssl_linux_x86_64_sources': [
'linux-x86_64/crypto/aes/aes-x86_64.S',
'linux-x86_64/crypto/aes/aesni-x86_64.S',
'linux-x86_64/crypto/aes/bsaes-x86_64.S',
'linux-x86_64/crypto/aes/vpaes-x86_64.S',
'linux-x86_64/crypto/bn/rsaz-avx2.S',
'linux-x86_64/crypto/bn/rsaz-x86_64.S',
'linux-x86_64/crypto/bn/x86_64-mont.S',
'linux-x86_64/crypto/bn/x86_64-mont5.S',
'linux-x86_64/crypto/cpu-x86_64-asm.S',
'linux-x86_64/crypto/md5/md5-x86_64.S',
'linux-x86_64/crypto/modes/aesni-gcm-x86_64.S',
'linux-x86_64/crypto/modes/ghash-x86_64.S',
'linux-x86_64/crypto/rand/rdrand-x86_64.S',
'linux-x86_64/crypto/rc4/rc4-md5-x86_64.S',
'linux-x86_64/crypto/rc4/rc4-x86_64.S',
'linux-x86_64/crypto/sha/sha1-x86_64.S',
'linux-x86_64/crypto/sha/sha256-x86_64.S',
'linux-x86_64/crypto/sha/sha512-x86_64.S',
],
'boringssl_mac_x86_sources': [
'mac-x86/crypto/aes/aes-586.S',
'mac-x86/crypto/aes/aesni-x86.S',
'mac-x86/crypto/aes/vpaes-x86.S',
'mac-x86/crypto/bn/bn-586.S',
'mac-x86/crypto/bn/co-586.S',
'mac-x86/crypto/bn/x86-mont.S',
'mac-x86/crypto/cpu-x86-asm.S',
'mac-x86/crypto/md5/md5-586.S',
'mac-x86/crypto/modes/ghash-x86.S',
'mac-x86/crypto/rc4/rc4-586.S',
'mac-x86/crypto/sha/sha1-586.S',
'mac-x86/crypto/sha/sha256-586.S',
'mac-x86/crypto/sha/sha512-586.S',
],
'boringssl_mac_x86_64_sources': [
'mac-x86_64/crypto/aes/aes-x86_64.S',
'mac-x86_64/crypto/aes/aesni-x86_64.S',
'mac-x86_64/crypto/aes/bsaes-x86_64.S',
'mac-x86_64/crypto/aes/vpaes-x86_64.S',
'mac-x86_64/crypto/bn/rsaz-avx2.S',
'mac-x86_64/crypto/bn/rsaz-x86_64.S',
'mac-x86_64/crypto/bn/x86_64-mont.S',
'mac-x86_64/crypto/bn/x86_64-mont5.S',
'mac-x86_64/crypto/cpu-x86_64-asm.S',
'mac-x86_64/crypto/md5/md5-x86_64.S',
'mac-x86_64/crypto/modes/aesni-gcm-x86_64.S',
'mac-x86_64/crypto/modes/ghash-x86_64.S',
'mac-x86_64/crypto/rand/rdrand-x86_64.S',
'mac-x86_64/crypto/rc4/rc4-md5-x86_64.S',
'mac-x86_64/crypto/rc4/rc4-x86_64.S',
'mac-x86_64/crypto/sha/sha1-x86_64.S',
'mac-x86_64/crypto/sha/sha256-x86_64.S',
'mac-x86_64/crypto/sha/sha512-x86_64.S',
],
'boringssl_win_x86_sources': [
'win-x86/crypto/aes/aes-586.asm',
'win-x86/crypto/aes/aesni-x86.asm',
'win-x86/crypto/aes/vpaes-x86.asm',
'win-x86/crypto/bn/bn-586.asm',
'win-x86/crypto/bn/co-586.asm',
'win-x86/crypto/bn/x86-mont.asm',
'win-x86/crypto/cpu-x86-asm.asm',
'win-x86/crypto/md5/md5-586.asm',
'win-x86/crypto/modes/ghash-x86.asm',
'win-x86/crypto/rc4/rc4-586.asm',
'win-x86/crypto/sha/sha1-586.asm',
'win-x86/crypto/sha/sha256-586.asm',
'win-x86/crypto/sha/sha512-586.asm',
],
'boringssl_win_x86_64_sources': [
'win-x86_64/crypto/aes/aes-x86_64.asm',
'win-x86_64/crypto/aes/aesni-x86_64.asm',
'win-x86_64/crypto/aes/bsaes-x86_64.asm',
'win-x86_64/crypto/aes/vpaes-x86_64.asm',
'win-x86_64/crypto/bn/rsaz-avx2.asm',
'win-x86_64/crypto/bn/rsaz-x86_64.asm',
'win-x86_64/crypto/bn/x86_64-mont.asm',
'win-x86_64/crypto/bn/x86_64-mont5.asm',
'win-x86_64/crypto/cpu-x86_64-asm.asm',
'win-x86_64/crypto/md5/md5-x86_64.asm',
'win-x86_64/crypto/modes/aesni-gcm-x86_64.asm',
'win-x86_64/crypto/modes/ghash-x86_64.asm',
'win-x86_64/crypto/rand/rdrand-x86_64.asm',
'win-x86_64/crypto/rc4/rc4-md5-x86_64.asm',
'win-x86_64/crypto/rc4/rc4-x86_64.asm',
'win-x86_64/crypto/sha/sha1-x86_64.asm',
'win-x86_64/crypto/sha/sha256-x86_64.asm',
'win-x86_64/crypto/sha/sha512-x86_64.asm',
],
}
}

View File

@ -0,0 +1,99 @@
# Copyright (c) 2015, the Dart project authors. Please see the AUTHORS file
# for details. All rights reserved. Use of this source code is governed by a
# BSD-style license that can be found in the LICENSE file.
# This file is included to modify the configurations to build third-party
# code from BoringSSL.
# This code is C code, not C++, and is not warning-free, so we need to remove
# C++-specific flags, and add flags to supress the warnings in the code.
{
'variables': {
# Used by third_party/nss, which is from Chromium.
# Include the built-in set of root certificate authorities.
'exclude_nss_root_certs': 0,
'os_posix%': 1,
'os_bsd%': 0,
'chromeos%': 0,
'clang%': 0,
},
'target_defaults': {
'cflags': [
'-w',
'-UHAVE_CVAR_BUILT_ON_SEM',
],
# Removes these flags from the list cflags.
'cflags!': [
# NSS code from upstream mozilla builds with warnings,
# so we must allow warnings without failing.
'-Werror',
'-Wall',
'-ansi',
# Not supported for C, only for C++.
'-Wnon-virtual-dtor',
'-Wno-conversion-null',
'-fno-rtti',
'-fvisibility-inlines-hidden',
'-Woverloaded-virtual',
],
'configurations': {
'Dart_Base': {
'xcode_settings': {
'WARNING_CFLAGS': [
'-w',
],
'WARNING_CFLAGS!': [
'-Wall',
'-Wextra',
],
},
},
# Dart_Macos_Debug and Dart_Macos_Release are merged after
# Dart_Macos_Base, so we can override the 'ansi' and '-Werror' flags set
# at the global level in tools/gyp/configurations_xcode.gypi.
'Dart_Macos_Debug': {
'abstract': 1,
'xcode_settings': {
# Remove 'ansi' setting.
'GCC_C_LANGUAGE_STANDARD': 'c99',
'GCC_TREAT_WARNINGS_AS_ERRORS': 'NO', # -Werror off
},
},
'Dart_Macos_Release': {
'abstract': 1,
'xcode_settings': {
# Remove 'ansi' setting.
'GCC_C_LANGUAGE_STANDARD': 'c99',
'GCC_TREAT_WARNINGS_AS_ERRORS': 'NO', # -Werror off
},
},
# When being built for Android nss expects __linux__ to be defined.
'Dart_Android_Base': {
'target_conditions': [
['_toolset=="host"', {
'defines!': [
'ANDROID',
],
# Define __linux__ on Android build for NSS.
'defines': [
'__linux__',
],
'cflags!': [
'-U__linux__',
],
}],
['_toolset=="target"', {
'defines': [
'__linux__',
'CHECK_FORK_GETPID', # Android does not provide pthread_atfork.
'__USE_LARGEFILE64',
],
# Define __linux__ on Android build for NSS.
'cflags!': [
'-U__linux__',
],
}]
],
},
},
},
}

View File

@ -0,0 +1,62 @@
# Copyright 2014 The Chromium Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
{
'includes': [
'../../runtime/tools/gyp/runtime-configurations.gypi',
'boringssl_configurations.gypi',
],
'targets': [
{
'target_name': 'boringssl',
'type': '<(component)',
'toolsets': ['host', 'target'],
'includes': [
'boringssl.gypi',
],
'sources': [
'<@(boringssl_crypto_sources)',
'<@(boringssl_ssl_sources)',
],
'defines': [
'BORINGSSL_IMPLEMENTATION',
'BORINGSSL_NO_STATIC_INITIALIZER',
],
# TODO(davidben): Fix size_t truncations in BoringSSL.
# https://crbug.com/429039
'msvs_disabled_warnings': [ 4267, ],
'conditions': [
['OS == "mac"', {
'sources': [
'<@(boringssl_mac_x86_sources)',
'<@(boringssl_mac_x86_64_sources)'
],
}],
['OS == "linux" or OS == "android"', {
'sources': [
'<@(boringssl_linux_x86_64_sources)',
'<@(boringssl_linux_x86_sources)',
'<@(boringssl_linux_arm_sources)',
'<@(boringssl_linux_aarch64_sources)',
],
}],
['OS == "win"', {
'defines': [ 'OPENSSL_NO_ASM', 'WIN32_LEAN_AND_MEAN' ],
}],
],
'include_dirs': [
'src/include',
# This is for arm_arch.h, which is needed by some asm files. Since the
# asm files are generated and kept in a different directory, they
# cannot use relative paths to find this file.
'src/crypto',
],
'direct_dependent_settings': {
'include_dirs': [
'src/include',
],
},
},
],
}

View File

@ -0,0 +1,483 @@
# Copyright (c) 2014 The Chromium Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
# This file is created by generate_build_files.py. Do not edit manually.
{
'targets': [
{
'target_name': 'boringssl_base64_test',
'type': 'executable',
'dependencies': [
'boringssl.gyp:boringssl',
],
'sources': [
'src/crypto/base64/base64_test.cc',
'<@(boringssl_test_support_sources)',
],
# TODO(davidben): Fix size_t truncations in BoringSSL.
# https://crbug.com/429039
'msvs_disabled_warnings': [ 4267, ],
},
{
'target_name': 'boringssl_bio_test',
'type': 'executable',
'dependencies': [
'boringssl.gyp:boringssl',
],
'sources': [
'src/crypto/bio/bio_test.cc',
'<@(boringssl_test_support_sources)',
],
# TODO(davidben): Fix size_t truncations in BoringSSL.
# https://crbug.com/429039
'msvs_disabled_warnings': [ 4267, ],
},
{
'target_name': 'boringssl_bn_test',
'type': 'executable',
'dependencies': [
'boringssl.gyp:boringssl',
],
'sources': [
'src/crypto/bn/bn_test.cc',
'<@(boringssl_test_support_sources)',
],
# TODO(davidben): Fix size_t truncations in BoringSSL.
# https://crbug.com/429039
'msvs_disabled_warnings': [ 4267, ],
},
{
'target_name': 'boringssl_bytestring_test',
'type': 'executable',
'dependencies': [
'boringssl.gyp:boringssl',
],
'sources': [
'src/crypto/bytestring/bytestring_test.cc',
'<@(boringssl_test_support_sources)',
],
# TODO(davidben): Fix size_t truncations in BoringSSL.
# https://crbug.com/429039
'msvs_disabled_warnings': [ 4267, ],
},
{
'target_name': 'boringssl_aead_test',
'type': 'executable',
'dependencies': [
'boringssl.gyp:boringssl',
],
'sources': [
'src/crypto/cipher/aead_test.cc',
'<@(boringssl_test_support_sources)',
],
# TODO(davidben): Fix size_t truncations in BoringSSL.
# https://crbug.com/429039
'msvs_disabled_warnings': [ 4267, ],
},
{
'target_name': 'boringssl_cipher_test',
'type': 'executable',
'dependencies': [
'boringssl.gyp:boringssl',
],
'sources': [
'src/crypto/cipher/cipher_test.cc',
'<@(boringssl_test_support_sources)',
],
# TODO(davidben): Fix size_t truncations in BoringSSL.
# https://crbug.com/429039
'msvs_disabled_warnings': [ 4267, ],
},
{
'target_name': 'boringssl_cmac_test',
'type': 'executable',
'dependencies': [
'boringssl.gyp:boringssl',
],
'sources': [
'src/crypto/cmac/cmac_test.cc',
'<@(boringssl_test_support_sources)',
],
# TODO(davidben): Fix size_t truncations in BoringSSL.
# https://crbug.com/429039
'msvs_disabled_warnings': [ 4267, ],
},
{
'target_name': 'boringssl_constant_time_test',
'type': 'executable',
'dependencies': [
'boringssl.gyp:boringssl',
],
'sources': [
'src/crypto/constant_time_test.c',
'<@(boringssl_test_support_sources)',
],
# TODO(davidben): Fix size_t truncations in BoringSSL.
# https://crbug.com/429039
'msvs_disabled_warnings': [ 4267, ],
},
{
'target_name': 'boringssl_dh_test',
'type': 'executable',
'dependencies': [
'boringssl.gyp:boringssl',
],
'sources': [
'src/crypto/dh/dh_test.cc',
'<@(boringssl_test_support_sources)',
],
# TODO(davidben): Fix size_t truncations in BoringSSL.
# https://crbug.com/429039
'msvs_disabled_warnings': [ 4267, ],
},
{
'target_name': 'boringssl_digest_test',
'type': 'executable',
'dependencies': [
'boringssl.gyp:boringssl',
],
'sources': [
'src/crypto/digest/digest_test.cc',
'<@(boringssl_test_support_sources)',
],
# TODO(davidben): Fix size_t truncations in BoringSSL.
# https://crbug.com/429039
'msvs_disabled_warnings': [ 4267, ],
},
{
'target_name': 'boringssl_dsa_test',
'type': 'executable',
'dependencies': [
'boringssl.gyp:boringssl',
],
'sources': [
'src/crypto/dsa/dsa_test.c',
'<@(boringssl_test_support_sources)',
],
# TODO(davidben): Fix size_t truncations in BoringSSL.
# https://crbug.com/429039
'msvs_disabled_warnings': [ 4267, ],
},
{
'target_name': 'boringssl_ec_test',
'type': 'executable',
'dependencies': [
'boringssl.gyp:boringssl',
],
'sources': [
'src/crypto/ec/ec_test.cc',
'<@(boringssl_test_support_sources)',
],
# TODO(davidben): Fix size_t truncations in BoringSSL.
# https://crbug.com/429039
'msvs_disabled_warnings': [ 4267, ],
},
{
'target_name': 'boringssl_example_mul',
'type': 'executable',
'dependencies': [
'boringssl.gyp:boringssl',
],
'sources': [
'src/crypto/ec/example_mul.c',
'<@(boringssl_test_support_sources)',
],
# TODO(davidben): Fix size_t truncations in BoringSSL.
# https://crbug.com/429039
'msvs_disabled_warnings': [ 4267, ],
},
{
'target_name': 'boringssl_ecdsa_test',
'type': 'executable',
'dependencies': [
'boringssl.gyp:boringssl',
],
'sources': [
'src/crypto/ecdsa/ecdsa_test.cc',
'<@(boringssl_test_support_sources)',
],
# TODO(davidben): Fix size_t truncations in BoringSSL.
# https://crbug.com/429039
'msvs_disabled_warnings': [ 4267, ],
},
{
'target_name': 'boringssl_err_test',
'type': 'executable',
'dependencies': [
'boringssl.gyp:boringssl',
],
'sources': [
'src/crypto/err/err_test.cc',
'<@(boringssl_test_support_sources)',
],
# TODO(davidben): Fix size_t truncations in BoringSSL.
# https://crbug.com/429039
'msvs_disabled_warnings': [ 4267, ],
},
{
'target_name': 'boringssl_evp_extra_test',
'type': 'executable',
'dependencies': [
'boringssl.gyp:boringssl',
],
'sources': [
'src/crypto/evp/evp_extra_test.cc',
'<@(boringssl_test_support_sources)',
],
# TODO(davidben): Fix size_t truncations in BoringSSL.
# https://crbug.com/429039
'msvs_disabled_warnings': [ 4267, ],
},
{
'target_name': 'boringssl_evp_test',
'type': 'executable',
'dependencies': [
'boringssl.gyp:boringssl',
],
'sources': [
'src/crypto/evp/evp_test.cc',
'<@(boringssl_test_support_sources)',
],
# TODO(davidben): Fix size_t truncations in BoringSSL.
# https://crbug.com/429039
'msvs_disabled_warnings': [ 4267, ],
},
{
'target_name': 'boringssl_pbkdf_test',
'type': 'executable',
'dependencies': [
'boringssl.gyp:boringssl',
],
'sources': [
'src/crypto/evp/pbkdf_test.cc',
'<@(boringssl_test_support_sources)',
],
# TODO(davidben): Fix size_t truncations in BoringSSL.
# https://crbug.com/429039
'msvs_disabled_warnings': [ 4267, ],
},
{
'target_name': 'boringssl_hkdf_test',
'type': 'executable',
'dependencies': [
'boringssl.gyp:boringssl',
],
'sources': [
'src/crypto/hkdf/hkdf_test.c',
'<@(boringssl_test_support_sources)',
],
# TODO(davidben): Fix size_t truncations in BoringSSL.
# https://crbug.com/429039
'msvs_disabled_warnings': [ 4267, ],
},
{
'target_name': 'boringssl_hmac_test',
'type': 'executable',
'dependencies': [
'boringssl.gyp:boringssl',
],
'sources': [
'src/crypto/hmac/hmac_test.cc',
'<@(boringssl_test_support_sources)',
],
# TODO(davidben): Fix size_t truncations in BoringSSL.
# https://crbug.com/429039
'msvs_disabled_warnings': [ 4267, ],
},
{
'target_name': 'boringssl_lhash_test',
'type': 'executable',
'dependencies': [
'boringssl.gyp:boringssl',
],
'sources': [
'src/crypto/lhash/lhash_test.c',
'<@(boringssl_test_support_sources)',
],
# TODO(davidben): Fix size_t truncations in BoringSSL.
# https://crbug.com/429039
'msvs_disabled_warnings': [ 4267, ],
},
{
'target_name': 'boringssl_gcm_test',
'type': 'executable',
'dependencies': [
'boringssl.gyp:boringssl',
],
'sources': [
'src/crypto/modes/gcm_test.c',
'<@(boringssl_test_support_sources)',
],
# TODO(davidben): Fix size_t truncations in BoringSSL.
# https://crbug.com/429039
'msvs_disabled_warnings': [ 4267, ],
},
{
'target_name': 'boringssl_pkcs12_test',
'type': 'executable',
'dependencies': [
'boringssl.gyp:boringssl',
],
'sources': [
'src/crypto/pkcs8/pkcs12_test.cc',
'<@(boringssl_test_support_sources)',
],
# TODO(davidben): Fix size_t truncations in BoringSSL.
# https://crbug.com/429039
'msvs_disabled_warnings': [ 4267, ],
},
{
'target_name': 'boringssl_refcount_test',
'type': 'executable',
'dependencies': [
'boringssl.gyp:boringssl',
],
'sources': [
'src/crypto/refcount_test.c',
'<@(boringssl_test_support_sources)',
],
# TODO(davidben): Fix size_t truncations in BoringSSL.
# https://crbug.com/429039
'msvs_disabled_warnings': [ 4267, ],
},
{
'target_name': 'boringssl_rsa_test',
'type': 'executable',
'dependencies': [
'boringssl.gyp:boringssl',
],
'sources': [
'src/crypto/rsa/rsa_test.cc',
'<@(boringssl_test_support_sources)',
],
# TODO(davidben): Fix size_t truncations in BoringSSL.
# https://crbug.com/429039
'msvs_disabled_warnings': [ 4267, ],
},
{
'target_name': 'boringssl_thread_test',
'type': 'executable',
'dependencies': [
'boringssl.gyp:boringssl',
],
'sources': [
'src/crypto/thread_test.c',
'<@(boringssl_test_support_sources)',
],
# TODO(davidben): Fix size_t truncations in BoringSSL.
# https://crbug.com/429039
'msvs_disabled_warnings': [ 4267, ],
},
{
'target_name': 'boringssl_pkcs7_test',
'type': 'executable',
'dependencies': [
'boringssl.gyp:boringssl',
],
'sources': [
'src/crypto/x509/pkcs7_test.c',
'<@(boringssl_test_support_sources)',
],
# TODO(davidben): Fix size_t truncations in BoringSSL.
# https://crbug.com/429039
'msvs_disabled_warnings': [ 4267, ],
},
{
'target_name': 'boringssl_tab_test',
'type': 'executable',
'dependencies': [
'boringssl.gyp:boringssl',
],
'sources': [
'src/crypto/x509v3/tab_test.c',
'<@(boringssl_test_support_sources)',
],
# TODO(davidben): Fix size_t truncations in BoringSSL.
# https://crbug.com/429039
'msvs_disabled_warnings': [ 4267, ],
},
{
'target_name': 'boringssl_v3name_test',
'type': 'executable',
'dependencies': [
'boringssl.gyp:boringssl',
],
'sources': [
'src/crypto/x509v3/v3name_test.c',
'<@(boringssl_test_support_sources)',
],
# TODO(davidben): Fix size_t truncations in BoringSSL.
# https://crbug.com/429039
'msvs_disabled_warnings': [ 4267, ],
},
{
'target_name': 'boringssl_pqueue_test',
'type': 'executable',
'dependencies': [
'boringssl.gyp:boringssl',
],
'sources': [
'src/ssl/pqueue/pqueue_test.c',
'<@(boringssl_test_support_sources)',
],
# TODO(davidben): Fix size_t truncations in BoringSSL.
# https://crbug.com/429039
'msvs_disabled_warnings': [ 4267, ],
},
{
'target_name': 'boringssl_ssl_test',
'type': 'executable',
'dependencies': [
'boringssl.gyp:boringssl',
],
'sources': [
'src/ssl/ssl_test.cc',
'<@(boringssl_test_support_sources)',
],
# TODO(davidben): Fix size_t truncations in BoringSSL.
# https://crbug.com/429039
'msvs_disabled_warnings': [ 4267, ],
},
],
'variables': {
'boringssl_test_support_sources': [
'src/crypto/test/file_test.cc',
'src/crypto/test/malloc.cc',
],
'boringssl_test_targets': [
'boringssl_aead_test',
'boringssl_base64_test',
'boringssl_bio_test',
'boringssl_bn_test',
'boringssl_bytestring_test',
'boringssl_cipher_test',
'boringssl_cmac_test',
'boringssl_constant_time_test',
'boringssl_dh_test',
'boringssl_digest_test',
'boringssl_dsa_test',
'boringssl_ec_test',
'boringssl_ecdsa_test',
'boringssl_err_test',
'boringssl_evp_extra_test',
'boringssl_evp_test',
'boringssl_example_mul',
'boringssl_gcm_test',
'boringssl_hkdf_test',
'boringssl_hmac_test',
'boringssl_lhash_test',
'boringssl_pbkdf_test',
'boringssl_pkcs12_test',
'boringssl_pkcs7_test',
'boringssl_pqueue_test',
'boringssl_refcount_test',
'boringssl_rsa_test',
'boringssl_ssl_test',
'boringssl_tab_test',
'boringssl_thread_test',
'boringssl_v3name_test',
],
}
}

2678
third_party/boringssl/err_data.c vendored Normal file

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,751 @@
#if defined(__aarch64__)
#include "arm_arch.h"
#if __ARM_MAX_ARCH__>=7
.text
#if !defined(__clang__)
.arch armv8-a+crypto
#endif
.align 5
.Lrcon:
.long 0x01,0x01,0x01,0x01
.long 0x0c0f0e0d,0x0c0f0e0d,0x0c0f0e0d,0x0c0f0e0d // rotate-n-splat
.long 0x1b,0x1b,0x1b,0x1b
.globl aes_v8_set_encrypt_key
.type aes_v8_set_encrypt_key,%function
.align 5
aes_v8_set_encrypt_key:
.Lenc_key:
stp x29,x30,[sp,#-16]!
add x29,sp,#0
mov x3,#-1
cmp x0,#0
b.eq .Lenc_key_abort
cmp x2,#0
b.eq .Lenc_key_abort
mov x3,#-2
cmp w1,#128
b.lt .Lenc_key_abort
cmp w1,#256
b.gt .Lenc_key_abort
tst w1,#0x3f
b.ne .Lenc_key_abort
adr x3,.Lrcon
cmp w1,#192
eor v0.16b,v0.16b,v0.16b
ld1 {v3.16b},[x0],#16
mov w1,#8 // reuse w1
ld1 {v1.4s,v2.4s},[x3],#32
b.lt .Loop128
b.eq .L192
b .L256
.align 4
.Loop128:
tbl v6.16b,{v3.16b},v2.16b
ext v5.16b,v0.16b,v3.16b,#12
st1 {v3.4s},[x2],#16
aese v6.16b,v0.16b
subs w1,w1,#1
eor v3.16b,v3.16b,v5.16b
ext v5.16b,v0.16b,v5.16b,#12
eor v3.16b,v3.16b,v5.16b
ext v5.16b,v0.16b,v5.16b,#12
eor v6.16b,v6.16b,v1.16b
eor v3.16b,v3.16b,v5.16b
shl v1.16b,v1.16b,#1
eor v3.16b,v3.16b,v6.16b
b.ne .Loop128
ld1 {v1.4s},[x3]
tbl v6.16b,{v3.16b},v2.16b
ext v5.16b,v0.16b,v3.16b,#12
st1 {v3.4s},[x2],#16
aese v6.16b,v0.16b
eor v3.16b,v3.16b,v5.16b
ext v5.16b,v0.16b,v5.16b,#12
eor v3.16b,v3.16b,v5.16b
ext v5.16b,v0.16b,v5.16b,#12
eor v6.16b,v6.16b,v1.16b
eor v3.16b,v3.16b,v5.16b
shl v1.16b,v1.16b,#1
eor v3.16b,v3.16b,v6.16b
tbl v6.16b,{v3.16b},v2.16b
ext v5.16b,v0.16b,v3.16b,#12
st1 {v3.4s},[x2],#16
aese v6.16b,v0.16b
eor v3.16b,v3.16b,v5.16b
ext v5.16b,v0.16b,v5.16b,#12
eor v3.16b,v3.16b,v5.16b
ext v5.16b,v0.16b,v5.16b,#12
eor v6.16b,v6.16b,v1.16b
eor v3.16b,v3.16b,v5.16b
eor v3.16b,v3.16b,v6.16b
st1 {v3.4s},[x2]
add x2,x2,#0x50
mov w12,#10
b .Ldone
.align 4
.L192:
ld1 {v4.8b},[x0],#8
movi v6.16b,#8 // borrow v6.16b
st1 {v3.4s},[x2],#16
sub v2.16b,v2.16b,v6.16b // adjust the mask
.Loop192:
tbl v6.16b,{v4.16b},v2.16b
ext v5.16b,v0.16b,v3.16b,#12
st1 {v4.8b},[x2],#8
aese v6.16b,v0.16b
subs w1,w1,#1
eor v3.16b,v3.16b,v5.16b
ext v5.16b,v0.16b,v5.16b,#12
eor v3.16b,v3.16b,v5.16b
ext v5.16b,v0.16b,v5.16b,#12
eor v3.16b,v3.16b,v5.16b
dup v5.4s,v3.s[3]
eor v5.16b,v5.16b,v4.16b
eor v6.16b,v6.16b,v1.16b
ext v4.16b,v0.16b,v4.16b,#12
shl v1.16b,v1.16b,#1
eor v4.16b,v4.16b,v5.16b
eor v3.16b,v3.16b,v6.16b
eor v4.16b,v4.16b,v6.16b
st1 {v3.4s},[x2],#16
b.ne .Loop192
mov w12,#12
add x2,x2,#0x20
b .Ldone
.align 4
.L256:
ld1 {v4.16b},[x0]
mov w1,#7
mov w12,#14
st1 {v3.4s},[x2],#16
.Loop256:
tbl v6.16b,{v4.16b},v2.16b
ext v5.16b,v0.16b,v3.16b,#12
st1 {v4.4s},[x2],#16
aese v6.16b,v0.16b
subs w1,w1,#1
eor v3.16b,v3.16b,v5.16b
ext v5.16b,v0.16b,v5.16b,#12
eor v3.16b,v3.16b,v5.16b
ext v5.16b,v0.16b,v5.16b,#12
eor v6.16b,v6.16b,v1.16b
eor v3.16b,v3.16b,v5.16b
shl v1.16b,v1.16b,#1
eor v3.16b,v3.16b,v6.16b
st1 {v3.4s},[x2],#16
b.eq .Ldone
dup v6.4s,v3.s[3] // just splat
ext v5.16b,v0.16b,v4.16b,#12
aese v6.16b,v0.16b
eor v4.16b,v4.16b,v5.16b
ext v5.16b,v0.16b,v5.16b,#12
eor v4.16b,v4.16b,v5.16b
ext v5.16b,v0.16b,v5.16b,#12
eor v4.16b,v4.16b,v5.16b
eor v4.16b,v4.16b,v6.16b
b .Loop256
.Ldone:
str w12,[x2]
mov x3,#0
.Lenc_key_abort:
mov x0,x3 // return value
ldr x29,[sp],#16
ret
.size aes_v8_set_encrypt_key,.-aes_v8_set_encrypt_key
.globl aes_v8_set_decrypt_key
.type aes_v8_set_decrypt_key,%function
.align 5
aes_v8_set_decrypt_key:
stp x29,x30,[sp,#-16]!
add x29,sp,#0
bl .Lenc_key
cmp x0,#0
b.ne .Ldec_key_abort
sub x2,x2,#240 // restore original x2
mov x4,#-16
add x0,x2,x12,lsl#4 // end of key schedule
ld1 {v0.4s},[x2]
ld1 {v1.4s},[x0]
st1 {v0.4s},[x0],x4
st1 {v1.4s},[x2],#16
.Loop_imc:
ld1 {v0.4s},[x2]
ld1 {v1.4s},[x0]
aesimc v0.16b,v0.16b
aesimc v1.16b,v1.16b
st1 {v0.4s},[x0],x4
st1 {v1.4s},[x2],#16
cmp x0,x2
b.hi .Loop_imc
ld1 {v0.4s},[x2]
aesimc v0.16b,v0.16b
st1 {v0.4s},[x0]
eor x0,x0,x0 // return value
.Ldec_key_abort:
ldp x29,x30,[sp],#16
ret
.size aes_v8_set_decrypt_key,.-aes_v8_set_decrypt_key
.globl aes_v8_encrypt
.type aes_v8_encrypt,%function
.align 5
aes_v8_encrypt:
ldr w3,[x2,#240]
ld1 {v0.4s},[x2],#16
ld1 {v2.16b},[x0]
sub w3,w3,#2
ld1 {v1.4s},[x2],#16
.Loop_enc:
aese v2.16b,v0.16b
aesmc v2.16b,v2.16b
ld1 {v0.4s},[x2],#16
subs w3,w3,#2
aese v2.16b,v1.16b
aesmc v2.16b,v2.16b
ld1 {v1.4s},[x2],#16
b.gt .Loop_enc
aese v2.16b,v0.16b
aesmc v2.16b,v2.16b
ld1 {v0.4s},[x2]
aese v2.16b,v1.16b
eor v2.16b,v2.16b,v0.16b
st1 {v2.16b},[x1]
ret
.size aes_v8_encrypt,.-aes_v8_encrypt
.globl aes_v8_decrypt
.type aes_v8_decrypt,%function
.align 5
aes_v8_decrypt:
ldr w3,[x2,#240]
ld1 {v0.4s},[x2],#16
ld1 {v2.16b},[x0]
sub w3,w3,#2
ld1 {v1.4s},[x2],#16
.Loop_dec:
aesd v2.16b,v0.16b
aesimc v2.16b,v2.16b
ld1 {v0.4s},[x2],#16
subs w3,w3,#2
aesd v2.16b,v1.16b
aesimc v2.16b,v2.16b
ld1 {v1.4s},[x2],#16
b.gt .Loop_dec
aesd v2.16b,v0.16b
aesimc v2.16b,v2.16b
ld1 {v0.4s},[x2]
aesd v2.16b,v1.16b
eor v2.16b,v2.16b,v0.16b
st1 {v2.16b},[x1]
ret
.size aes_v8_decrypt,.-aes_v8_decrypt
.globl aes_v8_cbc_encrypt
.type aes_v8_cbc_encrypt,%function
.align 5
aes_v8_cbc_encrypt:
stp x29,x30,[sp,#-16]!
add x29,sp,#0
subs x2,x2,#16
mov x8,#16
b.lo .Lcbc_abort
csel x8,xzr,x8,eq
cmp w5,#0 // en- or decrypting?
ldr w5,[x3,#240]
and x2,x2,#-16
ld1 {v6.16b},[x4]
ld1 {v0.16b},[x0],x8
ld1 {v16.4s,v17.4s},[x3] // load key schedule...
sub w5,w5,#6
add x7,x3,x5,lsl#4 // pointer to last 7 round keys
sub w5,w5,#2
ld1 {v18.4s,v19.4s},[x7],#32
ld1 {v20.4s,v21.4s},[x7],#32
ld1 {v22.4s,v23.4s},[x7],#32
ld1 {v7.4s},[x7]
add x7,x3,#32
mov w6,w5
b.eq .Lcbc_dec
cmp w5,#2
eor v0.16b,v0.16b,v6.16b
eor v5.16b,v16.16b,v7.16b
b.eq .Lcbc_enc128
ld1 {v2.4s,v3.4s},[x7]
add x7,x3,#16
add x6,x3,#16*4
add x12,x3,#16*5
aese v0.16b,v16.16b
aesmc v0.16b,v0.16b
add x14,x3,#16*6
add x3,x3,#16*7
b .Lenter_cbc_enc
.align 4
.Loop_cbc_enc:
aese v0.16b,v16.16b
aesmc v0.16b,v0.16b
st1 {v6.16b},[x1],#16
.Lenter_cbc_enc:
aese v0.16b,v17.16b
aesmc v0.16b,v0.16b
aese v0.16b,v2.16b
aesmc v0.16b,v0.16b
ld1 {v16.4s},[x6]
cmp w5,#4
aese v0.16b,v3.16b
aesmc v0.16b,v0.16b
ld1 {v17.4s},[x12]
b.eq .Lcbc_enc192
aese v0.16b,v16.16b
aesmc v0.16b,v0.16b
ld1 {v16.4s},[x14]
aese v0.16b,v17.16b
aesmc v0.16b,v0.16b
ld1 {v17.4s},[x3]
nop
.Lcbc_enc192:
aese v0.16b,v16.16b
aesmc v0.16b,v0.16b
subs x2,x2,#16
aese v0.16b,v17.16b
aesmc v0.16b,v0.16b
csel x8,xzr,x8,eq
aese v0.16b,v18.16b
aesmc v0.16b,v0.16b
aese v0.16b,v19.16b
aesmc v0.16b,v0.16b
ld1 {v16.16b},[x0],x8
aese v0.16b,v20.16b
aesmc v0.16b,v0.16b
eor v16.16b,v16.16b,v5.16b
aese v0.16b,v21.16b
aesmc v0.16b,v0.16b
ld1 {v17.4s},[x7] // re-pre-load rndkey[1]
aese v0.16b,v22.16b
aesmc v0.16b,v0.16b
aese v0.16b,v23.16b
eor v6.16b,v0.16b,v7.16b
b.hs .Loop_cbc_enc
st1 {v6.16b},[x1],#16
b .Lcbc_done
.align 5
.Lcbc_enc128:
ld1 {v2.4s,v3.4s},[x7]
aese v0.16b,v16.16b
aesmc v0.16b,v0.16b
b .Lenter_cbc_enc128
.Loop_cbc_enc128:
aese v0.16b,v16.16b
aesmc v0.16b,v0.16b
st1 {v6.16b},[x1],#16
.Lenter_cbc_enc128:
aese v0.16b,v17.16b
aesmc v0.16b,v0.16b
subs x2,x2,#16
aese v0.16b,v2.16b
aesmc v0.16b,v0.16b
csel x8,xzr,x8,eq
aese v0.16b,v3.16b
aesmc v0.16b,v0.16b
aese v0.16b,v18.16b
aesmc v0.16b,v0.16b
aese v0.16b,v19.16b
aesmc v0.16b,v0.16b
ld1 {v16.16b},[x0],x8
aese v0.16b,v20.16b
aesmc v0.16b,v0.16b
aese v0.16b,v21.16b
aesmc v0.16b,v0.16b
aese v0.16b,v22.16b
aesmc v0.16b,v0.16b
eor v16.16b,v16.16b,v5.16b
aese v0.16b,v23.16b
eor v6.16b,v0.16b,v7.16b
b.hs .Loop_cbc_enc128
st1 {v6.16b},[x1],#16
b .Lcbc_done
.align 5
.Lcbc_dec:
ld1 {v18.16b},[x0],#16
subs x2,x2,#32 // bias
add w6,w5,#2
orr v3.16b,v0.16b,v0.16b
orr v1.16b,v0.16b,v0.16b
orr v19.16b,v18.16b,v18.16b
b.lo .Lcbc_dec_tail
orr v1.16b,v18.16b,v18.16b
ld1 {v18.16b},[x0],#16
orr v2.16b,v0.16b,v0.16b
orr v3.16b,v1.16b,v1.16b
orr v19.16b,v18.16b,v18.16b
.Loop3x_cbc_dec:
aesd v0.16b,v16.16b
aesimc v0.16b,v0.16b
aesd v1.16b,v16.16b
aesimc v1.16b,v1.16b
aesd v18.16b,v16.16b
aesimc v18.16b,v18.16b
ld1 {v16.4s},[x7],#16
subs w6,w6,#2
aesd v0.16b,v17.16b
aesimc v0.16b,v0.16b
aesd v1.16b,v17.16b
aesimc v1.16b,v1.16b
aesd v18.16b,v17.16b
aesimc v18.16b,v18.16b
ld1 {v17.4s},[x7],#16
b.gt .Loop3x_cbc_dec
aesd v0.16b,v16.16b
aesimc v0.16b,v0.16b
aesd v1.16b,v16.16b
aesimc v1.16b,v1.16b
aesd v18.16b,v16.16b
aesimc v18.16b,v18.16b
eor v4.16b,v6.16b,v7.16b
subs x2,x2,#0x30
eor v5.16b,v2.16b,v7.16b
csel x6,x2,x6,lo // x6, w6, is zero at this point
aesd v0.16b,v17.16b
aesimc v0.16b,v0.16b
aesd v1.16b,v17.16b
aesimc v1.16b,v1.16b
aesd v18.16b,v17.16b
aesimc v18.16b,v18.16b
eor v17.16b,v3.16b,v7.16b
add x0,x0,x6 // x0 is adjusted in such way that
// at exit from the loop v1.16b-v18.16b
// are loaded with last "words"
orr v6.16b,v19.16b,v19.16b
mov x7,x3
aesd v0.16b,v20.16b
aesimc v0.16b,v0.16b
aesd v1.16b,v20.16b
aesimc v1.16b,v1.16b
aesd v18.16b,v20.16b
aesimc v18.16b,v18.16b
ld1 {v2.16b},[x0],#16
aesd v0.16b,v21.16b
aesimc v0.16b,v0.16b
aesd v1.16b,v21.16b
aesimc v1.16b,v1.16b
aesd v18.16b,v21.16b
aesimc v18.16b,v18.16b
ld1 {v3.16b},[x0],#16
aesd v0.16b,v22.16b
aesimc v0.16b,v0.16b
aesd v1.16b,v22.16b
aesimc v1.16b,v1.16b
aesd v18.16b,v22.16b
aesimc v18.16b,v18.16b
ld1 {v19.16b},[x0],#16
aesd v0.16b,v23.16b
aesd v1.16b,v23.16b
aesd v18.16b,v23.16b
ld1 {v16.4s},[x7],#16 // re-pre-load rndkey[0]
add w6,w5,#2
eor v4.16b,v4.16b,v0.16b
eor v5.16b,v5.16b,v1.16b
eor v18.16b,v18.16b,v17.16b
ld1 {v17.4s},[x7],#16 // re-pre-load rndkey[1]
st1 {v4.16b},[x1],#16
orr v0.16b,v2.16b,v2.16b
st1 {v5.16b},[x1],#16
orr v1.16b,v3.16b,v3.16b
st1 {v18.16b},[x1],#16
orr v18.16b,v19.16b,v19.16b
b.hs .Loop3x_cbc_dec
cmn x2,#0x30
b.eq .Lcbc_done
nop
.Lcbc_dec_tail:
aesd v1.16b,v16.16b
aesimc v1.16b,v1.16b
aesd v18.16b,v16.16b
aesimc v18.16b,v18.16b
ld1 {v16.4s},[x7],#16
subs w6,w6,#2
aesd v1.16b,v17.16b
aesimc v1.16b,v1.16b
aesd v18.16b,v17.16b
aesimc v18.16b,v18.16b
ld1 {v17.4s},[x7],#16
b.gt .Lcbc_dec_tail
aesd v1.16b,v16.16b
aesimc v1.16b,v1.16b
aesd v18.16b,v16.16b
aesimc v18.16b,v18.16b
aesd v1.16b,v17.16b
aesimc v1.16b,v1.16b
aesd v18.16b,v17.16b
aesimc v18.16b,v18.16b
aesd v1.16b,v20.16b
aesimc v1.16b,v1.16b
aesd v18.16b,v20.16b
aesimc v18.16b,v18.16b
cmn x2,#0x20
aesd v1.16b,v21.16b
aesimc v1.16b,v1.16b
aesd v18.16b,v21.16b
aesimc v18.16b,v18.16b
eor v5.16b,v6.16b,v7.16b
aesd v1.16b,v22.16b
aesimc v1.16b,v1.16b
aesd v18.16b,v22.16b
aesimc v18.16b,v18.16b
eor v17.16b,v3.16b,v7.16b
aesd v1.16b,v23.16b
aesd v18.16b,v23.16b
b.eq .Lcbc_dec_one
eor v5.16b,v5.16b,v1.16b
eor v17.16b,v17.16b,v18.16b
orr v6.16b,v19.16b,v19.16b
st1 {v5.16b},[x1],#16
st1 {v17.16b},[x1],#16
b .Lcbc_done
.Lcbc_dec_one:
eor v5.16b,v5.16b,v18.16b
orr v6.16b,v19.16b,v19.16b
st1 {v5.16b},[x1],#16
.Lcbc_done:
st1 {v6.16b},[x4]
.Lcbc_abort:
ldr x29,[sp],#16
ret
.size aes_v8_cbc_encrypt,.-aes_v8_cbc_encrypt
.globl aes_v8_ctr32_encrypt_blocks
.type aes_v8_ctr32_encrypt_blocks,%function
.align 5
aes_v8_ctr32_encrypt_blocks:
stp x29,x30,[sp,#-16]!
add x29,sp,#0
ldr w5,[x3,#240]
ldr w8, [x4, #12]
ld1 {v0.4s},[x4]
ld1 {v16.4s,v17.4s},[x3] // load key schedule...
sub w5,w5,#4
mov x12,#16
cmp x2,#2
add x7,x3,x5,lsl#4 // pointer to last 5 round keys
sub w5,w5,#2
ld1 {v20.4s,v21.4s},[x7],#32
ld1 {v22.4s,v23.4s},[x7],#32
ld1 {v7.4s},[x7]
add x7,x3,#32
mov w6,w5
csel x12,xzr,x12,lo
#ifndef __ARMEB__
rev w8, w8
#endif
orr v1.16b,v0.16b,v0.16b
add w10, w8, #1
orr v18.16b,v0.16b,v0.16b
add w8, w8, #2
orr v6.16b,v0.16b,v0.16b
rev w10, w10
mov v1.s[3],w10
b.ls .Lctr32_tail
rev w12, w8
sub x2,x2,#3 // bias
mov v18.s[3],w12
b .Loop3x_ctr32
.align 4
.Loop3x_ctr32:
aese v0.16b,v16.16b
aesmc v0.16b,v0.16b
aese v1.16b,v16.16b
aesmc v1.16b,v1.16b
aese v18.16b,v16.16b
aesmc v18.16b,v18.16b
ld1 {v16.4s},[x7],#16
subs w6,w6,#2
aese v0.16b,v17.16b
aesmc v0.16b,v0.16b
aese v1.16b,v17.16b
aesmc v1.16b,v1.16b
aese v18.16b,v17.16b
aesmc v18.16b,v18.16b
ld1 {v17.4s},[x7],#16
b.gt .Loop3x_ctr32
aese v0.16b,v16.16b
aesmc v4.16b,v0.16b
aese v1.16b,v16.16b
aesmc v5.16b,v1.16b
ld1 {v2.16b},[x0],#16
orr v0.16b,v6.16b,v6.16b
aese v18.16b,v16.16b
aesmc v18.16b,v18.16b
ld1 {v3.16b},[x0],#16
orr v1.16b,v6.16b,v6.16b
aese v4.16b,v17.16b
aesmc v4.16b,v4.16b
aese v5.16b,v17.16b
aesmc v5.16b,v5.16b
ld1 {v19.16b},[x0],#16
mov x7,x3
aese v18.16b,v17.16b
aesmc v17.16b,v18.16b
orr v18.16b,v6.16b,v6.16b
add w9,w8,#1
aese v4.16b,v20.16b
aesmc v4.16b,v4.16b
aese v5.16b,v20.16b
aesmc v5.16b,v5.16b
eor v2.16b,v2.16b,v7.16b
add w10,w8,#2
aese v17.16b,v20.16b
aesmc v17.16b,v17.16b
eor v3.16b,v3.16b,v7.16b
add w8,w8,#3
aese v4.16b,v21.16b
aesmc v4.16b,v4.16b
aese v5.16b,v21.16b
aesmc v5.16b,v5.16b
eor v19.16b,v19.16b,v7.16b
rev w9,w9
aese v17.16b,v21.16b
aesmc v17.16b,v17.16b
mov v0.s[3], w9
rev w10,w10
aese v4.16b,v22.16b
aesmc v4.16b,v4.16b
aese v5.16b,v22.16b
aesmc v5.16b,v5.16b
mov v1.s[3], w10
rev w12,w8
aese v17.16b,v22.16b
aesmc v17.16b,v17.16b
mov v18.s[3], w12
subs x2,x2,#3
aese v4.16b,v23.16b
aese v5.16b,v23.16b
aese v17.16b,v23.16b
eor v2.16b,v2.16b,v4.16b
ld1 {v16.4s},[x7],#16 // re-pre-load rndkey[0]
st1 {v2.16b},[x1],#16
eor v3.16b,v3.16b,v5.16b
mov w6,w5
st1 {v3.16b},[x1],#16
eor v19.16b,v19.16b,v17.16b
ld1 {v17.4s},[x7],#16 // re-pre-load rndkey[1]
st1 {v19.16b},[x1],#16
b.hs .Loop3x_ctr32
adds x2,x2,#3
b.eq .Lctr32_done
cmp x2,#1
mov x12,#16
csel x12,xzr,x12,eq
.Lctr32_tail:
aese v0.16b,v16.16b
aesmc v0.16b,v0.16b
aese v1.16b,v16.16b
aesmc v1.16b,v1.16b
ld1 {v16.4s},[x7],#16
subs w6,w6,#2
aese v0.16b,v17.16b
aesmc v0.16b,v0.16b
aese v1.16b,v17.16b
aesmc v1.16b,v1.16b
ld1 {v17.4s},[x7],#16
b.gt .Lctr32_tail
aese v0.16b,v16.16b
aesmc v0.16b,v0.16b
aese v1.16b,v16.16b
aesmc v1.16b,v1.16b
aese v0.16b,v17.16b
aesmc v0.16b,v0.16b
aese v1.16b,v17.16b
aesmc v1.16b,v1.16b
ld1 {v2.16b},[x0],x12
aese v0.16b,v20.16b
aesmc v0.16b,v0.16b
aese v1.16b,v20.16b
aesmc v1.16b,v1.16b
ld1 {v3.16b},[x0]
aese v0.16b,v21.16b
aesmc v0.16b,v0.16b
aese v1.16b,v21.16b
aesmc v1.16b,v1.16b
eor v2.16b,v2.16b,v7.16b
aese v0.16b,v22.16b
aesmc v0.16b,v0.16b
aese v1.16b,v22.16b
aesmc v1.16b,v1.16b
eor v3.16b,v3.16b,v7.16b
aese v0.16b,v23.16b
aese v1.16b,v23.16b
cmp x2,#1
eor v2.16b,v2.16b,v0.16b
eor v3.16b,v3.16b,v1.16b
st1 {v2.16b},[x1],#16
b.eq .Lctr32_done
st1 {v3.16b},[x1]
.Lctr32_done:
ldr x29,[sp],#16
ret
.size aes_v8_ctr32_encrypt_blocks,.-aes_v8_ctr32_encrypt_blocks
#endif
#endif

View File

@ -0,0 +1,232 @@
#if defined(__aarch64__)
#include "arm_arch.h"
.text
#if !defined(__clang__)
.arch armv8-a+crypto
#endif
.globl gcm_init_v8
.type gcm_init_v8,%function
.align 4
gcm_init_v8:
ld1 {v17.2d},[x1] //load input H
movi v19.16b,#0xe1
shl v19.2d,v19.2d,#57 //0xc2.0
ext v3.16b,v17.16b,v17.16b,#8
ushr v18.2d,v19.2d,#63
dup v17.4s,v17.s[1]
ext v16.16b,v18.16b,v19.16b,#8 //t0=0xc2....01
ushr v18.2d,v3.2d,#63
sshr v17.4s,v17.4s,#31 //broadcast carry bit
and v18.16b,v18.16b,v16.16b
shl v3.2d,v3.2d,#1
ext v18.16b,v18.16b,v18.16b,#8
and v16.16b,v16.16b,v17.16b
orr v3.16b,v3.16b,v18.16b //H<<<=1
eor v20.16b,v3.16b,v16.16b //twisted H
st1 {v20.2d},[x0],#16 //store Htable[0]
//calculate H^2
ext v16.16b,v20.16b,v20.16b,#8 //Karatsuba pre-processing
pmull v0.1q,v20.1d,v20.1d
eor v16.16b,v16.16b,v20.16b
pmull2 v2.1q,v20.2d,v20.2d
pmull v1.1q,v16.1d,v16.1d
ext v17.16b,v0.16b,v2.16b,#8 //Karatsuba post-processing
eor v18.16b,v0.16b,v2.16b
eor v1.16b,v1.16b,v17.16b
eor v1.16b,v1.16b,v18.16b
pmull v18.1q,v0.1d,v19.1d //1st phase
ins v2.d[0],v1.d[1]
ins v1.d[1],v0.d[0]
eor v0.16b,v1.16b,v18.16b
ext v18.16b,v0.16b,v0.16b,#8 //2nd phase
pmull v0.1q,v0.1d,v19.1d
eor v18.16b,v18.16b,v2.16b
eor v22.16b,v0.16b,v18.16b
ext v17.16b,v22.16b,v22.16b,#8 //Karatsuba pre-processing
eor v17.16b,v17.16b,v22.16b
ext v21.16b,v16.16b,v17.16b,#8 //pack Karatsuba pre-processed
st1 {v21.2d,v22.2d},[x0] //store Htable[1..2]
ret
.size gcm_init_v8,.-gcm_init_v8
.globl gcm_gmult_v8
.type gcm_gmult_v8,%function
.align 4
gcm_gmult_v8:
ld1 {v17.2d},[x0] //load Xi
movi v19.16b,#0xe1
ld1 {v20.2d,v21.2d},[x1] //load twisted H, ...
shl v19.2d,v19.2d,#57
#ifndef __ARMEB__
rev64 v17.16b,v17.16b
#endif
ext v3.16b,v17.16b,v17.16b,#8
pmull v0.1q,v20.1d,v3.1d //H.loˇXi.lo
eor v17.16b,v17.16b,v3.16b //Karatsuba pre-processing
pmull2 v2.1q,v20.2d,v3.2d //H.hiˇXi.hi
pmull v1.1q,v21.1d,v17.1d //(H.lo+H.hi)ˇ(Xi.lo+Xi.hi)
ext v17.16b,v0.16b,v2.16b,#8 //Karatsuba post-processing
eor v18.16b,v0.16b,v2.16b
eor v1.16b,v1.16b,v17.16b
eor v1.16b,v1.16b,v18.16b
pmull v18.1q,v0.1d,v19.1d //1st phase of reduction
ins v2.d[0],v1.d[1]
ins v1.d[1],v0.d[0]
eor v0.16b,v1.16b,v18.16b
ext v18.16b,v0.16b,v0.16b,#8 //2nd phase of reduction
pmull v0.1q,v0.1d,v19.1d
eor v18.16b,v18.16b,v2.16b
eor v0.16b,v0.16b,v18.16b
#ifndef __ARMEB__
rev64 v0.16b,v0.16b
#endif
ext v0.16b,v0.16b,v0.16b,#8
st1 {v0.2d},[x0] //write out Xi
ret
.size gcm_gmult_v8,.-gcm_gmult_v8
.globl gcm_ghash_v8
.type gcm_ghash_v8,%function
.align 4
gcm_ghash_v8:
ld1 {v0.2d},[x0] //load [rotated] Xi
//"[rotated]" means that
//loaded value would have
//to be rotated in order to
//make it appear as in
//alorithm specification
subs x3,x3,#32 //see if x3 is 32 or larger
mov x12,#16 //x12 is used as post-
//increment for input pointer;
//as loop is modulo-scheduled
//x12 is zeroed just in time
//to preclude oversteping
//inp[len], which means that
//last block[s] are actually
//loaded twice, but last
//copy is not processed
ld1 {v20.2d,v21.2d},[x1],#32 //load twisted H, ..., H^2
movi v19.16b,#0xe1
ld1 {v22.2d},[x1]
csel x12,xzr,x12,eq //is it time to zero x12?
ext v0.16b,v0.16b,v0.16b,#8 //rotate Xi
ld1 {v16.2d},[x2],#16 //load [rotated] I[0]
shl v19.2d,v19.2d,#57 //compose 0xc2.0 constant
#ifndef __ARMEB__
rev64 v16.16b,v16.16b
rev64 v0.16b,v0.16b
#endif
ext v3.16b,v16.16b,v16.16b,#8 //rotate I[0]
b.lo .Lodd_tail_v8 //x3 was less than 32
ld1 {v17.2d},[x2],x12 //load [rotated] I[1]
#ifndef __ARMEB__
rev64 v17.16b,v17.16b
#endif
ext v7.16b,v17.16b,v17.16b,#8
eor v3.16b,v3.16b,v0.16b //I[i]^=Xi
pmull v4.1q,v20.1d,v7.1d //HˇIi+1
eor v17.16b,v17.16b,v7.16b //Karatsuba pre-processing
pmull2 v6.1q,v20.2d,v7.2d
b .Loop_mod2x_v8
.align 4
.Loop_mod2x_v8:
ext v18.16b,v3.16b,v3.16b,#8
subs x3,x3,#32 //is there more data?
pmull v0.1q,v22.1d,v3.1d //H^2.loˇXi.lo
csel x12,xzr,x12,lo //is it time to zero x12?
pmull v5.1q,v21.1d,v17.1d
eor v18.16b,v18.16b,v3.16b //Karatsuba pre-processing
pmull2 v2.1q,v22.2d,v3.2d //H^2.hiˇXi.hi
eor v0.16b,v0.16b,v4.16b //accumulate
pmull2 v1.1q,v21.2d,v18.2d //(H^2.lo+H^2.hi)ˇ(Xi.lo+Xi.hi)
ld1 {v16.2d},[x2],x12 //load [rotated] I[i+2]
eor v2.16b,v2.16b,v6.16b
csel x12,xzr,x12,eq //is it time to zero x12?
eor v1.16b,v1.16b,v5.16b
ext v17.16b,v0.16b,v2.16b,#8 //Karatsuba post-processing
eor v18.16b,v0.16b,v2.16b
eor v1.16b,v1.16b,v17.16b
ld1 {v17.2d},[x2],x12 //load [rotated] I[i+3]
#ifndef __ARMEB__
rev64 v16.16b,v16.16b
#endif
eor v1.16b,v1.16b,v18.16b
pmull v18.1q,v0.1d,v19.1d //1st phase of reduction
#ifndef __ARMEB__
rev64 v17.16b,v17.16b
#endif
ins v2.d[0],v1.d[1]
ins v1.d[1],v0.d[0]
ext v7.16b,v17.16b,v17.16b,#8
ext v3.16b,v16.16b,v16.16b,#8
eor v0.16b,v1.16b,v18.16b
pmull v4.1q,v20.1d,v7.1d //HˇIi+1
eor v3.16b,v3.16b,v2.16b //accumulate v3.16b early
ext v18.16b,v0.16b,v0.16b,#8 //2nd phase of reduction
pmull v0.1q,v0.1d,v19.1d
eor v3.16b,v3.16b,v18.16b
eor v17.16b,v17.16b,v7.16b //Karatsuba pre-processing
eor v3.16b,v3.16b,v0.16b
pmull2 v6.1q,v20.2d,v7.2d
b.hs .Loop_mod2x_v8 //there was at least 32 more bytes
eor v2.16b,v2.16b,v18.16b
ext v3.16b,v16.16b,v16.16b,#8 //re-construct v3.16b
adds x3,x3,#32 //re-construct x3
eor v0.16b,v0.16b,v2.16b //re-construct v0.16b
b.eq .Ldone_v8 //is x3 zero?
.Lodd_tail_v8:
ext v18.16b,v0.16b,v0.16b,#8
eor v3.16b,v3.16b,v0.16b //inp^=Xi
eor v17.16b,v16.16b,v18.16b //v17.16b is rotated inp^Xi
pmull v0.1q,v20.1d,v3.1d //H.loˇXi.lo
eor v17.16b,v17.16b,v3.16b //Karatsuba pre-processing
pmull2 v2.1q,v20.2d,v3.2d //H.hiˇXi.hi
pmull v1.1q,v21.1d,v17.1d //(H.lo+H.hi)ˇ(Xi.lo+Xi.hi)
ext v17.16b,v0.16b,v2.16b,#8 //Karatsuba post-processing
eor v18.16b,v0.16b,v2.16b
eor v1.16b,v1.16b,v17.16b
eor v1.16b,v1.16b,v18.16b
pmull v18.1q,v0.1d,v19.1d //1st phase of reduction
ins v2.d[0],v1.d[1]
ins v1.d[1],v0.d[0]
eor v0.16b,v1.16b,v18.16b
ext v18.16b,v0.16b,v0.16b,#8 //2nd phase of reduction
pmull v0.1q,v0.1d,v19.1d
eor v18.16b,v18.16b,v2.16b
eor v0.16b,v0.16b,v18.16b
.Ldone_v8:
#ifndef __ARMEB__
rev64 v0.16b,v0.16b
#endif
ext v0.16b,v0.16b,v0.16b,#8
st1 {v0.2d},[x0] //write out Xi
ret
.size gcm_ghash_v8,.-gcm_ghash_v8
.byte 71,72,65,83,72,32,102,111,114,32,65,82,77,118,56,44,32,67,82,89,80,84,79,71,65,77,83,32,98,121,32,60,97,112,112,114,111,64,111,112,101,110,115,115,108,46,111,114,103,62,0
.align 2
.align 2
#endif

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,756 @@
#if defined(__arm__)
#include "arm_arch.h"
#if __ARM_MAX_ARCH__>=7
.text
.arch armv7-a
.fpu neon
.code 32
.align 5
.Lrcon:
.long 0x01,0x01,0x01,0x01
.long 0x0c0f0e0d,0x0c0f0e0d,0x0c0f0e0d,0x0c0f0e0d @ rotate-n-splat
.long 0x1b,0x1b,0x1b,0x1b
.globl aes_v8_set_encrypt_key
.type aes_v8_set_encrypt_key,%function
.align 5
aes_v8_set_encrypt_key:
.Lenc_key:
mov r3,#-1
cmp r0,#0
beq .Lenc_key_abort
cmp r2,#0
beq .Lenc_key_abort
mov r3,#-2
cmp r1,#128
blt .Lenc_key_abort
cmp r1,#256
bgt .Lenc_key_abort
tst r1,#0x3f
bne .Lenc_key_abort
adr r3,.Lrcon
cmp r1,#192
veor q0,q0,q0
vld1.8 {q3},[r0]!
mov r1,#8 @ reuse r1
vld1.32 {q1,q2},[r3]!
blt .Loop128
beq .L192
b .L256
.align 4
.Loop128:
vtbl.8 d20,{q3},d4
vtbl.8 d21,{q3},d5
vext.8 q9,q0,q3,#12
vst1.32 {q3},[r2]!
.byte 0x00,0x43,0xf0,0xf3 @ aese q10,q0
subs r1,r1,#1
veor q3,q3,q9
vext.8 q9,q0,q9,#12
veor q3,q3,q9
vext.8 q9,q0,q9,#12
veor q10,q10,q1
veor q3,q3,q9
vshl.u8 q1,q1,#1
veor q3,q3,q10
bne .Loop128
vld1.32 {q1},[r3]
vtbl.8 d20,{q3},d4
vtbl.8 d21,{q3},d5
vext.8 q9,q0,q3,#12
vst1.32 {q3},[r2]!
.byte 0x00,0x43,0xf0,0xf3 @ aese q10,q0
veor q3,q3,q9
vext.8 q9,q0,q9,#12
veor q3,q3,q9
vext.8 q9,q0,q9,#12
veor q10,q10,q1
veor q3,q3,q9
vshl.u8 q1,q1,#1
veor q3,q3,q10
vtbl.8 d20,{q3},d4
vtbl.8 d21,{q3},d5
vext.8 q9,q0,q3,#12
vst1.32 {q3},[r2]!
.byte 0x00,0x43,0xf0,0xf3 @ aese q10,q0
veor q3,q3,q9
vext.8 q9,q0,q9,#12
veor q3,q3,q9
vext.8 q9,q0,q9,#12
veor q10,q10,q1
veor q3,q3,q9
veor q3,q3,q10
vst1.32 {q3},[r2]
add r2,r2,#0x50
mov r12,#10
b .Ldone
.align 4
.L192:
vld1.8 {d16},[r0]!
vmov.i8 q10,#8 @ borrow q10
vst1.32 {q3},[r2]!
vsub.i8 q2,q2,q10 @ adjust the mask
.Loop192:
vtbl.8 d20,{q8},d4
vtbl.8 d21,{q8},d5
vext.8 q9,q0,q3,#12
vst1.32 {d16},[r2]!
.byte 0x00,0x43,0xf0,0xf3 @ aese q10,q0
subs r1,r1,#1
veor q3,q3,q9
vext.8 q9,q0,q9,#12
veor q3,q3,q9
vext.8 q9,q0,q9,#12
veor q3,q3,q9
vdup.32 q9,d7[1]
veor q9,q9,q8
veor q10,q10,q1
vext.8 q8,q0,q8,#12
vshl.u8 q1,q1,#1
veor q8,q8,q9
veor q3,q3,q10
veor q8,q8,q10
vst1.32 {q3},[r2]!
bne .Loop192
mov r12,#12
add r2,r2,#0x20
b .Ldone
.align 4
.L256:
vld1.8 {q8},[r0]
mov r1,#7
mov r12,#14
vst1.32 {q3},[r2]!
.Loop256:
vtbl.8 d20,{q8},d4
vtbl.8 d21,{q8},d5
vext.8 q9,q0,q3,#12
vst1.32 {q8},[r2]!
.byte 0x00,0x43,0xf0,0xf3 @ aese q10,q0
subs r1,r1,#1
veor q3,q3,q9
vext.8 q9,q0,q9,#12
veor q3,q3,q9
vext.8 q9,q0,q9,#12
veor q10,q10,q1
veor q3,q3,q9
vshl.u8 q1,q1,#1
veor q3,q3,q10
vst1.32 {q3},[r2]!
beq .Ldone
vdup.32 q10,d7[1]
vext.8 q9,q0,q8,#12
.byte 0x00,0x43,0xf0,0xf3 @ aese q10,q0
veor q8,q8,q9
vext.8 q9,q0,q9,#12
veor q8,q8,q9
vext.8 q9,q0,q9,#12
veor q8,q8,q9
veor q8,q8,q10
b .Loop256
.Ldone:
str r12,[r2]
mov r3,#0
.Lenc_key_abort:
mov r0,r3 @ return value
bx lr
.size aes_v8_set_encrypt_key,.-aes_v8_set_encrypt_key
.globl aes_v8_set_decrypt_key
.type aes_v8_set_decrypt_key,%function
.align 5
aes_v8_set_decrypt_key:
stmdb sp!,{r4,lr}
bl .Lenc_key
cmp r0,#0
bne .Ldec_key_abort
sub r2,r2,#240 @ restore original r2
mov r4,#-16
add r0,r2,r12,lsl#4 @ end of key schedule
vld1.32 {q0},[r2]
vld1.32 {q1},[r0]
vst1.32 {q0},[r0],r4
vst1.32 {q1},[r2]!
.Loop_imc:
vld1.32 {q0},[r2]
vld1.32 {q1},[r0]
.byte 0xc0,0x03,0xb0,0xf3 @ aesimc q0,q0
.byte 0xc2,0x23,0xb0,0xf3 @ aesimc q1,q1
vst1.32 {q0},[r0],r4
vst1.32 {q1},[r2]!
cmp r0,r2
bhi .Loop_imc
vld1.32 {q0},[r2]
.byte 0xc0,0x03,0xb0,0xf3 @ aesimc q0,q0
vst1.32 {q0},[r0]
eor r0,r0,r0 @ return value
.Ldec_key_abort:
ldmia sp!,{r4,pc}
.size aes_v8_set_decrypt_key,.-aes_v8_set_decrypt_key
.globl aes_v8_encrypt
.type aes_v8_encrypt,%function
.align 5
aes_v8_encrypt:
ldr r3,[r2,#240]
vld1.32 {q0},[r2]!
vld1.8 {q2},[r0]
sub r3,r3,#2
vld1.32 {q1},[r2]!
.Loop_enc:
.byte 0x00,0x43,0xb0,0xf3 @ aese q2,q0
.byte 0x84,0x43,0xb0,0xf3 @ aesmc q2,q2
vld1.32 {q0},[r2]!
subs r3,r3,#2
.byte 0x02,0x43,0xb0,0xf3 @ aese q2,q1
.byte 0x84,0x43,0xb0,0xf3 @ aesmc q2,q2
vld1.32 {q1},[r2]!
bgt .Loop_enc
.byte 0x00,0x43,0xb0,0xf3 @ aese q2,q0
.byte 0x84,0x43,0xb0,0xf3 @ aesmc q2,q2
vld1.32 {q0},[r2]
.byte 0x02,0x43,0xb0,0xf3 @ aese q2,q1
veor q2,q2,q0
vst1.8 {q2},[r1]
bx lr
.size aes_v8_encrypt,.-aes_v8_encrypt
.globl aes_v8_decrypt
.type aes_v8_decrypt,%function
.align 5
aes_v8_decrypt:
ldr r3,[r2,#240]
vld1.32 {q0},[r2]!
vld1.8 {q2},[r0]
sub r3,r3,#2
vld1.32 {q1},[r2]!
.Loop_dec:
.byte 0x40,0x43,0xb0,0xf3 @ aesd q2,q0
.byte 0xc4,0x43,0xb0,0xf3 @ aesimc q2,q2
vld1.32 {q0},[r2]!
subs r3,r3,#2
.byte 0x42,0x43,0xb0,0xf3 @ aesd q2,q1
.byte 0xc4,0x43,0xb0,0xf3 @ aesimc q2,q2
vld1.32 {q1},[r2]!
bgt .Loop_dec
.byte 0x40,0x43,0xb0,0xf3 @ aesd q2,q0
.byte 0xc4,0x43,0xb0,0xf3 @ aesimc q2,q2
vld1.32 {q0},[r2]
.byte 0x42,0x43,0xb0,0xf3 @ aesd q2,q1
veor q2,q2,q0
vst1.8 {q2},[r1]
bx lr
.size aes_v8_decrypt,.-aes_v8_decrypt
.globl aes_v8_cbc_encrypt
.type aes_v8_cbc_encrypt,%function
.align 5
aes_v8_cbc_encrypt:
mov ip,sp
stmdb sp!,{r4,r5,r6,r7,r8,lr}
vstmdb sp!,{d8,d9,d10,d11,d12,d13,d14,d15} @ ABI specification says so
ldmia ip,{r4,r5} @ load remaining args
subs r2,r2,#16
mov r8,#16
blo .Lcbc_abort
moveq r8,#0
cmp r5,#0 @ en- or decrypting?
ldr r5,[r3,#240]
and r2,r2,#-16
vld1.8 {q6},[r4]
vld1.8 {q0},[r0],r8
vld1.32 {q8,q9},[r3] @ load key schedule...
sub r5,r5,#6
add r7,r3,r5,lsl#4 @ pointer to last 7 round keys
sub r5,r5,#2
vld1.32 {q10,q11},[r7]!
vld1.32 {q12,q13},[r7]!
vld1.32 {q14,q15},[r7]!
vld1.32 {q7},[r7]
add r7,r3,#32
mov r6,r5
beq .Lcbc_dec
cmp r5,#2
veor q0,q0,q6
veor q5,q8,q7
beq .Lcbc_enc128
vld1.32 {q2,q3},[r7]
add r7,r3,#16
add r6,r3,#16*4
add r12,r3,#16*5
.byte 0x20,0x03,0xb0,0xf3 @ aese q0,q8
.byte 0x80,0x03,0xb0,0xf3 @ aesmc q0,q0
add r14,r3,#16*6
add r3,r3,#16*7
b .Lenter_cbc_enc
.align 4
.Loop_cbc_enc:
.byte 0x20,0x03,0xb0,0xf3 @ aese q0,q8
.byte 0x80,0x03,0xb0,0xf3 @ aesmc q0,q0
vst1.8 {q6},[r1]!
.Lenter_cbc_enc:
.byte 0x22,0x03,0xb0,0xf3 @ aese q0,q9
.byte 0x80,0x03,0xb0,0xf3 @ aesmc q0,q0
.byte 0x04,0x03,0xb0,0xf3 @ aese q0,q2
.byte 0x80,0x03,0xb0,0xf3 @ aesmc q0,q0
vld1.32 {q8},[r6]
cmp r5,#4
.byte 0x06,0x03,0xb0,0xf3 @ aese q0,q3
.byte 0x80,0x03,0xb0,0xf3 @ aesmc q0,q0
vld1.32 {q9},[r12]
beq .Lcbc_enc192
.byte 0x20,0x03,0xb0,0xf3 @ aese q0,q8
.byte 0x80,0x03,0xb0,0xf3 @ aesmc q0,q0
vld1.32 {q8},[r14]
.byte 0x22,0x03,0xb0,0xf3 @ aese q0,q9
.byte 0x80,0x03,0xb0,0xf3 @ aesmc q0,q0
vld1.32 {q9},[r3]
nop
.Lcbc_enc192:
.byte 0x20,0x03,0xb0,0xf3 @ aese q0,q8
.byte 0x80,0x03,0xb0,0xf3 @ aesmc q0,q0
subs r2,r2,#16
.byte 0x22,0x03,0xb0,0xf3 @ aese q0,q9
.byte 0x80,0x03,0xb0,0xf3 @ aesmc q0,q0
moveq r8,#0
.byte 0x24,0x03,0xb0,0xf3 @ aese q0,q10
.byte 0x80,0x03,0xb0,0xf3 @ aesmc q0,q0
.byte 0x26,0x03,0xb0,0xf3 @ aese q0,q11
.byte 0x80,0x03,0xb0,0xf3 @ aesmc q0,q0
vld1.8 {q8},[r0],r8
.byte 0x28,0x03,0xb0,0xf3 @ aese q0,q12
.byte 0x80,0x03,0xb0,0xf3 @ aesmc q0,q0
veor q8,q8,q5
.byte 0x2a,0x03,0xb0,0xf3 @ aese q0,q13
.byte 0x80,0x03,0xb0,0xf3 @ aesmc q0,q0
vld1.32 {q9},[r7] @ re-pre-load rndkey[1]
.byte 0x2c,0x03,0xb0,0xf3 @ aese q0,q14
.byte 0x80,0x03,0xb0,0xf3 @ aesmc q0,q0
.byte 0x2e,0x03,0xb0,0xf3 @ aese q0,q15
veor q6,q0,q7
bhs .Loop_cbc_enc
vst1.8 {q6},[r1]!
b .Lcbc_done
.align 5
.Lcbc_enc128:
vld1.32 {q2,q3},[r7]
.byte 0x20,0x03,0xb0,0xf3 @ aese q0,q8
.byte 0x80,0x03,0xb0,0xf3 @ aesmc q0,q0
b .Lenter_cbc_enc128
.Loop_cbc_enc128:
.byte 0x20,0x03,0xb0,0xf3 @ aese q0,q8
.byte 0x80,0x03,0xb0,0xf3 @ aesmc q0,q0
vst1.8 {q6},[r1]!
.Lenter_cbc_enc128:
.byte 0x22,0x03,0xb0,0xf3 @ aese q0,q9
.byte 0x80,0x03,0xb0,0xf3 @ aesmc q0,q0
subs r2,r2,#16
.byte 0x04,0x03,0xb0,0xf3 @ aese q0,q2
.byte 0x80,0x03,0xb0,0xf3 @ aesmc q0,q0
moveq r8,#0
.byte 0x06,0x03,0xb0,0xf3 @ aese q0,q3
.byte 0x80,0x03,0xb0,0xf3 @ aesmc q0,q0
.byte 0x24,0x03,0xb0,0xf3 @ aese q0,q10
.byte 0x80,0x03,0xb0,0xf3 @ aesmc q0,q0
.byte 0x26,0x03,0xb0,0xf3 @ aese q0,q11
.byte 0x80,0x03,0xb0,0xf3 @ aesmc q0,q0
vld1.8 {q8},[r0],r8
.byte 0x28,0x03,0xb0,0xf3 @ aese q0,q12
.byte 0x80,0x03,0xb0,0xf3 @ aesmc q0,q0
.byte 0x2a,0x03,0xb0,0xf3 @ aese q0,q13
.byte 0x80,0x03,0xb0,0xf3 @ aesmc q0,q0
.byte 0x2c,0x03,0xb0,0xf3 @ aese q0,q14
.byte 0x80,0x03,0xb0,0xf3 @ aesmc q0,q0
veor q8,q8,q5
.byte 0x2e,0x03,0xb0,0xf3 @ aese q0,q15
veor q6,q0,q7
bhs .Loop_cbc_enc128
vst1.8 {q6},[r1]!
b .Lcbc_done
.align 5
.Lcbc_dec:
vld1.8 {q10},[r0]!
subs r2,r2,#32 @ bias
add r6,r5,#2
vorr q3,q0,q0
vorr q1,q0,q0
vorr q11,q10,q10
blo .Lcbc_dec_tail
vorr q1,q10,q10
vld1.8 {q10},[r0]!
vorr q2,q0,q0
vorr q3,q1,q1
vorr q11,q10,q10
.Loop3x_cbc_dec:
.byte 0x60,0x03,0xb0,0xf3 @ aesd q0,q8
.byte 0xc0,0x03,0xb0,0xf3 @ aesimc q0,q0
.byte 0x60,0x23,0xb0,0xf3 @ aesd q1,q8
.byte 0xc2,0x23,0xb0,0xf3 @ aesimc q1,q1
.byte 0x60,0x43,0xf0,0xf3 @ aesd q10,q8
.byte 0xe4,0x43,0xf0,0xf3 @ aesimc q10,q10
vld1.32 {q8},[r7]!
subs r6,r6,#2
.byte 0x62,0x03,0xb0,0xf3 @ aesd q0,q9
.byte 0xc0,0x03,0xb0,0xf3 @ aesimc q0,q0
.byte 0x62,0x23,0xb0,0xf3 @ aesd q1,q9
.byte 0xc2,0x23,0xb0,0xf3 @ aesimc q1,q1
.byte 0x62,0x43,0xf0,0xf3 @ aesd q10,q9
.byte 0xe4,0x43,0xf0,0xf3 @ aesimc q10,q10
vld1.32 {q9},[r7]!
bgt .Loop3x_cbc_dec
.byte 0x60,0x03,0xb0,0xf3 @ aesd q0,q8
.byte 0xc0,0x03,0xb0,0xf3 @ aesimc q0,q0
.byte 0x60,0x23,0xb0,0xf3 @ aesd q1,q8
.byte 0xc2,0x23,0xb0,0xf3 @ aesimc q1,q1
.byte 0x60,0x43,0xf0,0xf3 @ aesd q10,q8
.byte 0xe4,0x43,0xf0,0xf3 @ aesimc q10,q10
veor q4,q6,q7
subs r2,r2,#0x30
veor q5,q2,q7
movlo r6,r2 @ r6, r6, is zero at this point
.byte 0x62,0x03,0xb0,0xf3 @ aesd q0,q9
.byte 0xc0,0x03,0xb0,0xf3 @ aesimc q0,q0
.byte 0x62,0x23,0xb0,0xf3 @ aesd q1,q9
.byte 0xc2,0x23,0xb0,0xf3 @ aesimc q1,q1
.byte 0x62,0x43,0xf0,0xf3 @ aesd q10,q9
.byte 0xe4,0x43,0xf0,0xf3 @ aesimc q10,q10
veor q9,q3,q7
add r0,r0,r6 @ r0 is adjusted in such way that
@ at exit from the loop q1-q10
@ are loaded with last "words"
vorr q6,q11,q11
mov r7,r3
.byte 0x68,0x03,0xb0,0xf3 @ aesd q0,q12
.byte 0xc0,0x03,0xb0,0xf3 @ aesimc q0,q0
.byte 0x68,0x23,0xb0,0xf3 @ aesd q1,q12
.byte 0xc2,0x23,0xb0,0xf3 @ aesimc q1,q1
.byte 0x68,0x43,0xf0,0xf3 @ aesd q10,q12
.byte 0xe4,0x43,0xf0,0xf3 @ aesimc q10,q10
vld1.8 {q2},[r0]!
.byte 0x6a,0x03,0xb0,0xf3 @ aesd q0,q13
.byte 0xc0,0x03,0xb0,0xf3 @ aesimc q0,q0
.byte 0x6a,0x23,0xb0,0xf3 @ aesd q1,q13
.byte 0xc2,0x23,0xb0,0xf3 @ aesimc q1,q1
.byte 0x6a,0x43,0xf0,0xf3 @ aesd q10,q13
.byte 0xe4,0x43,0xf0,0xf3 @ aesimc q10,q10
vld1.8 {q3},[r0]!
.byte 0x6c,0x03,0xb0,0xf3 @ aesd q0,q14
.byte 0xc0,0x03,0xb0,0xf3 @ aesimc q0,q0
.byte 0x6c,0x23,0xb0,0xf3 @ aesd q1,q14
.byte 0xc2,0x23,0xb0,0xf3 @ aesimc q1,q1
.byte 0x6c,0x43,0xf0,0xf3 @ aesd q10,q14
.byte 0xe4,0x43,0xf0,0xf3 @ aesimc q10,q10
vld1.8 {q11},[r0]!
.byte 0x6e,0x03,0xb0,0xf3 @ aesd q0,q15
.byte 0x6e,0x23,0xb0,0xf3 @ aesd q1,q15
.byte 0x6e,0x43,0xf0,0xf3 @ aesd q10,q15
vld1.32 {q8},[r7]! @ re-pre-load rndkey[0]
add r6,r5,#2
veor q4,q4,q0
veor q5,q5,q1
veor q10,q10,q9
vld1.32 {q9},[r7]! @ re-pre-load rndkey[1]
vst1.8 {q4},[r1]!
vorr q0,q2,q2
vst1.8 {q5},[r1]!
vorr q1,q3,q3
vst1.8 {q10},[r1]!
vorr q10,q11,q11
bhs .Loop3x_cbc_dec
cmn r2,#0x30
beq .Lcbc_done
nop
.Lcbc_dec_tail:
.byte 0x60,0x23,0xb0,0xf3 @ aesd q1,q8
.byte 0xc2,0x23,0xb0,0xf3 @ aesimc q1,q1
.byte 0x60,0x43,0xf0,0xf3 @ aesd q10,q8
.byte 0xe4,0x43,0xf0,0xf3 @ aesimc q10,q10
vld1.32 {q8},[r7]!
subs r6,r6,#2
.byte 0x62,0x23,0xb0,0xf3 @ aesd q1,q9
.byte 0xc2,0x23,0xb0,0xf3 @ aesimc q1,q1
.byte 0x62,0x43,0xf0,0xf3 @ aesd q10,q9
.byte 0xe4,0x43,0xf0,0xf3 @ aesimc q10,q10
vld1.32 {q9},[r7]!
bgt .Lcbc_dec_tail
.byte 0x60,0x23,0xb0,0xf3 @ aesd q1,q8
.byte 0xc2,0x23,0xb0,0xf3 @ aesimc q1,q1
.byte 0x60,0x43,0xf0,0xf3 @ aesd q10,q8
.byte 0xe4,0x43,0xf0,0xf3 @ aesimc q10,q10
.byte 0x62,0x23,0xb0,0xf3 @ aesd q1,q9
.byte 0xc2,0x23,0xb0,0xf3 @ aesimc q1,q1
.byte 0x62,0x43,0xf0,0xf3 @ aesd q10,q9
.byte 0xe4,0x43,0xf0,0xf3 @ aesimc q10,q10
.byte 0x68,0x23,0xb0,0xf3 @ aesd q1,q12
.byte 0xc2,0x23,0xb0,0xf3 @ aesimc q1,q1
.byte 0x68,0x43,0xf0,0xf3 @ aesd q10,q12
.byte 0xe4,0x43,0xf0,0xf3 @ aesimc q10,q10
cmn r2,#0x20
.byte 0x6a,0x23,0xb0,0xf3 @ aesd q1,q13
.byte 0xc2,0x23,0xb0,0xf3 @ aesimc q1,q1
.byte 0x6a,0x43,0xf0,0xf3 @ aesd q10,q13
.byte 0xe4,0x43,0xf0,0xf3 @ aesimc q10,q10
veor q5,q6,q7
.byte 0x6c,0x23,0xb0,0xf3 @ aesd q1,q14
.byte 0xc2,0x23,0xb0,0xf3 @ aesimc q1,q1
.byte 0x6c,0x43,0xf0,0xf3 @ aesd q10,q14
.byte 0xe4,0x43,0xf0,0xf3 @ aesimc q10,q10
veor q9,q3,q7
.byte 0x6e,0x23,0xb0,0xf3 @ aesd q1,q15
.byte 0x6e,0x43,0xf0,0xf3 @ aesd q10,q15
beq .Lcbc_dec_one
veor q5,q5,q1
veor q9,q9,q10
vorr q6,q11,q11
vst1.8 {q5},[r1]!
vst1.8 {q9},[r1]!
b .Lcbc_done
.Lcbc_dec_one:
veor q5,q5,q10
vorr q6,q11,q11
vst1.8 {q5},[r1]!
.Lcbc_done:
vst1.8 {q6},[r4]
.Lcbc_abort:
vldmia sp!,{d8,d9,d10,d11,d12,d13,d14,d15}
ldmia sp!,{r4,r5,r6,r7,r8,pc}
.size aes_v8_cbc_encrypt,.-aes_v8_cbc_encrypt
.globl aes_v8_ctr32_encrypt_blocks
.type aes_v8_ctr32_encrypt_blocks,%function
.align 5
aes_v8_ctr32_encrypt_blocks:
mov ip,sp
stmdb sp!,{r4,r5,r6,r7,r8,r9,r10,lr}
vstmdb sp!,{d8,d9,d10,d11,d12,d13,d14,d15} @ ABI specification says so
ldr r4, [ip] @ load remaining arg
ldr r5,[r3,#240]
ldr r8, [r4, #12]
vld1.32 {q0},[r4]
vld1.32 {q8,q9},[r3] @ load key schedule...
sub r5,r5,#4
mov r12,#16
cmp r2,#2
add r7,r3,r5,lsl#4 @ pointer to last 5 round keys
sub r5,r5,#2
vld1.32 {q12,q13},[r7]!
vld1.32 {q14,q15},[r7]!
vld1.32 {q7},[r7]
add r7,r3,#32
mov r6,r5
movlo r12,#0
#ifndef __ARMEB__
rev r8, r8
#endif
vorr q1,q0,q0
add r10, r8, #1
vorr q10,q0,q0
add r8, r8, #2
vorr q6,q0,q0
rev r10, r10
vmov.32 d3[1],r10
bls .Lctr32_tail
rev r12, r8
sub r2,r2,#3 @ bias
vmov.32 d21[1],r12
b .Loop3x_ctr32
.align 4
.Loop3x_ctr32:
.byte 0x20,0x03,0xb0,0xf3 @ aese q0,q8
.byte 0x80,0x03,0xb0,0xf3 @ aesmc q0,q0
.byte 0x20,0x23,0xb0,0xf3 @ aese q1,q8
.byte 0x82,0x23,0xb0,0xf3 @ aesmc q1,q1
.byte 0x20,0x43,0xf0,0xf3 @ aese q10,q8
.byte 0xa4,0x43,0xf0,0xf3 @ aesmc q10,q10
vld1.32 {q8},[r7]!
subs r6,r6,#2
.byte 0x22,0x03,0xb0,0xf3 @ aese q0,q9
.byte 0x80,0x03,0xb0,0xf3 @ aesmc q0,q0
.byte 0x22,0x23,0xb0,0xf3 @ aese q1,q9
.byte 0x82,0x23,0xb0,0xf3 @ aesmc q1,q1
.byte 0x22,0x43,0xf0,0xf3 @ aese q10,q9
.byte 0xa4,0x43,0xf0,0xf3 @ aesmc q10,q10
vld1.32 {q9},[r7]!
bgt .Loop3x_ctr32
.byte 0x20,0x03,0xb0,0xf3 @ aese q0,q8
.byte 0x80,0x83,0xb0,0xf3 @ aesmc q4,q0
.byte 0x20,0x23,0xb0,0xf3 @ aese q1,q8
.byte 0x82,0xa3,0xb0,0xf3 @ aesmc q5,q1
vld1.8 {q2},[r0]!
vorr q0,q6,q6
.byte 0x20,0x43,0xf0,0xf3 @ aese q10,q8
.byte 0xa4,0x43,0xf0,0xf3 @ aesmc q10,q10
vld1.8 {q3},[r0]!
vorr q1,q6,q6
.byte 0x22,0x83,0xb0,0xf3 @ aese q4,q9
.byte 0x88,0x83,0xb0,0xf3 @ aesmc q4,q4
.byte 0x22,0xa3,0xb0,0xf3 @ aese q5,q9
.byte 0x8a,0xa3,0xb0,0xf3 @ aesmc q5,q5
vld1.8 {q11},[r0]!
mov r7,r3
.byte 0x22,0x43,0xf0,0xf3 @ aese q10,q9
.byte 0xa4,0x23,0xf0,0xf3 @ aesmc q9,q10
vorr q10,q6,q6
add r9,r8,#1
.byte 0x28,0x83,0xb0,0xf3 @ aese q4,q12
.byte 0x88,0x83,0xb0,0xf3 @ aesmc q4,q4
.byte 0x28,0xa3,0xb0,0xf3 @ aese q5,q12
.byte 0x8a,0xa3,0xb0,0xf3 @ aesmc q5,q5
veor q2,q2,q7
add r10,r8,#2
.byte 0x28,0x23,0xf0,0xf3 @ aese q9,q12
.byte 0xa2,0x23,0xf0,0xf3 @ aesmc q9,q9
veor q3,q3,q7
add r8,r8,#3
.byte 0x2a,0x83,0xb0,0xf3 @ aese q4,q13
.byte 0x88,0x83,0xb0,0xf3 @ aesmc q4,q4
.byte 0x2a,0xa3,0xb0,0xf3 @ aese q5,q13
.byte 0x8a,0xa3,0xb0,0xf3 @ aesmc q5,q5
veor q11,q11,q7
rev r9,r9
.byte 0x2a,0x23,0xf0,0xf3 @ aese q9,q13
.byte 0xa2,0x23,0xf0,0xf3 @ aesmc q9,q9
vmov.32 d1[1], r9
rev r10,r10
.byte 0x2c,0x83,0xb0,0xf3 @ aese q4,q14
.byte 0x88,0x83,0xb0,0xf3 @ aesmc q4,q4
.byte 0x2c,0xa3,0xb0,0xf3 @ aese q5,q14
.byte 0x8a,0xa3,0xb0,0xf3 @ aesmc q5,q5
vmov.32 d3[1], r10
rev r12,r8
.byte 0x2c,0x23,0xf0,0xf3 @ aese q9,q14
.byte 0xa2,0x23,0xf0,0xf3 @ aesmc q9,q9
vmov.32 d21[1], r12
subs r2,r2,#3
.byte 0x2e,0x83,0xb0,0xf3 @ aese q4,q15
.byte 0x2e,0xa3,0xb0,0xf3 @ aese q5,q15
.byte 0x2e,0x23,0xf0,0xf3 @ aese q9,q15
veor q2,q2,q4
vld1.32 {q8},[r7]! @ re-pre-load rndkey[0]
vst1.8 {q2},[r1]!
veor q3,q3,q5
mov r6,r5
vst1.8 {q3},[r1]!
veor q11,q11,q9
vld1.32 {q9},[r7]! @ re-pre-load rndkey[1]
vst1.8 {q11},[r1]!
bhs .Loop3x_ctr32
adds r2,r2,#3
beq .Lctr32_done
cmp r2,#1
mov r12,#16
moveq r12,#0
.Lctr32_tail:
.byte 0x20,0x03,0xb0,0xf3 @ aese q0,q8
.byte 0x80,0x03,0xb0,0xf3 @ aesmc q0,q0
.byte 0x20,0x23,0xb0,0xf3 @ aese q1,q8
.byte 0x82,0x23,0xb0,0xf3 @ aesmc q1,q1
vld1.32 {q8},[r7]!
subs r6,r6,#2
.byte 0x22,0x03,0xb0,0xf3 @ aese q0,q9
.byte 0x80,0x03,0xb0,0xf3 @ aesmc q0,q0
.byte 0x22,0x23,0xb0,0xf3 @ aese q1,q9
.byte 0x82,0x23,0xb0,0xf3 @ aesmc q1,q1
vld1.32 {q9},[r7]!
bgt .Lctr32_tail
.byte 0x20,0x03,0xb0,0xf3 @ aese q0,q8
.byte 0x80,0x03,0xb0,0xf3 @ aesmc q0,q0
.byte 0x20,0x23,0xb0,0xf3 @ aese q1,q8
.byte 0x82,0x23,0xb0,0xf3 @ aesmc q1,q1
.byte 0x22,0x03,0xb0,0xf3 @ aese q0,q9
.byte 0x80,0x03,0xb0,0xf3 @ aesmc q0,q0
.byte 0x22,0x23,0xb0,0xf3 @ aese q1,q9
.byte 0x82,0x23,0xb0,0xf3 @ aesmc q1,q1
vld1.8 {q2},[r0],r12
.byte 0x28,0x03,0xb0,0xf3 @ aese q0,q12
.byte 0x80,0x03,0xb0,0xf3 @ aesmc q0,q0
.byte 0x28,0x23,0xb0,0xf3 @ aese q1,q12
.byte 0x82,0x23,0xb0,0xf3 @ aesmc q1,q1
vld1.8 {q3},[r0]
.byte 0x2a,0x03,0xb0,0xf3 @ aese q0,q13
.byte 0x80,0x03,0xb0,0xf3 @ aesmc q0,q0
.byte 0x2a,0x23,0xb0,0xf3 @ aese q1,q13
.byte 0x82,0x23,0xb0,0xf3 @ aesmc q1,q1
veor q2,q2,q7
.byte 0x2c,0x03,0xb0,0xf3 @ aese q0,q14
.byte 0x80,0x03,0xb0,0xf3 @ aesmc q0,q0
.byte 0x2c,0x23,0xb0,0xf3 @ aese q1,q14
.byte 0x82,0x23,0xb0,0xf3 @ aesmc q1,q1
veor q3,q3,q7
.byte 0x2e,0x03,0xb0,0xf3 @ aese q0,q15
.byte 0x2e,0x23,0xb0,0xf3 @ aese q1,q15
cmp r2,#1
veor q2,q2,q0
veor q3,q3,q1
vst1.8 {q2},[r1]!
beq .Lctr32_done
vst1.8 {q3},[r1]
.Lctr32_done:
vldmia sp!,{d8,d9,d10,d11,d12,d13,d14,d15}
ldmia sp!,{r4,r5,r6,r7,r8,r9,r10,pc}
.size aes_v8_ctr32_encrypt_blocks,.-aes_v8_ctr32_encrypt_blocks
#endif
#endif

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,589 @@
#if defined(__arm__)
#include "arm_arch.h"
.text
.code 32
#if __ARM_MAX_ARCH__>=7
.align 5
.LOPENSSL_armcap:
.word OPENSSL_armcap_P-.Lbn_mul_mont
#endif
.globl bn_mul_mont
.hidden bn_mul_mont
.type bn_mul_mont,%function
.align 5
bn_mul_mont:
.Lbn_mul_mont:
ldr ip,[sp,#4] @ load num
stmdb sp!,{r0,r2} @ sp points at argument block
#if __ARM_MAX_ARCH__>=7
tst ip,#7
bne .Lialu
adr r0,bn_mul_mont
ldr r2,.LOPENSSL_armcap
ldr r0,[r0,r2]
#ifdef __APPLE__
ldr r0,[r0]
#endif
tst r0,#1 @ NEON available?
ldmia sp, {r0,r2}
beq .Lialu
add sp,sp,#8
b bn_mul8x_mont_neon
.align 4
.Lialu:
#endif
cmp ip,#2
mov r0,ip @ load num
movlt r0,#0
addlt sp,sp,#2*4
blt .Labrt
stmdb sp!,{r4,r5,r6,r7,r8,r9,r10,r11,r12,lr} @ save 10 registers
mov r0,r0,lsl#2 @ rescale r0 for byte count
sub sp,sp,r0 @ alloca(4*num)
sub sp,sp,#4 @ +extra dword
sub r0,r0,#4 @ "num=num-1"
add r4,r2,r0 @ &bp[num-1]
add r0,sp,r0 @ r0 to point at &tp[num-1]
ldr r8,[r0,#14*4] @ &n0
ldr r2,[r2] @ bp[0]
ldr r5,[r1],#4 @ ap[0],ap++
ldr r6,[r3],#4 @ np[0],np++
ldr r8,[r8] @ *n0
str r4,[r0,#15*4] @ save &bp[num]
umull r10,r11,r5,r2 @ ap[0]*bp[0]
str r8,[r0,#14*4] @ save n0 value
mul r8,r10,r8 @ "tp[0]"*n0
mov r12,#0
umlal r10,r12,r6,r8 @ np[0]*n0+"t[0]"
mov r4,sp
.L1st:
ldr r5,[r1],#4 @ ap[j],ap++
mov r10,r11
ldr r6,[r3],#4 @ np[j],np++
mov r11,#0
umlal r10,r11,r5,r2 @ ap[j]*bp[0]
mov r14,#0
umlal r12,r14,r6,r8 @ np[j]*n0
adds r12,r12,r10
str r12,[r4],#4 @ tp[j-1]=,tp++
adc r12,r14,#0
cmp r4,r0
bne .L1st
adds r12,r12,r11
ldr r4,[r0,#13*4] @ restore bp
mov r14,#0
ldr r8,[r0,#14*4] @ restore n0
adc r14,r14,#0
str r12,[r0] @ tp[num-1]=
str r14,[r0,#4] @ tp[num]=
.Louter:
sub r7,r0,sp @ "original" r0-1 value
sub r1,r1,r7 @ "rewind" ap to &ap[1]
ldr r2,[r4,#4]! @ *(++bp)
sub r3,r3,r7 @ "rewind" np to &np[1]
ldr r5,[r1,#-4] @ ap[0]
ldr r10,[sp] @ tp[0]
ldr r6,[r3,#-4] @ np[0]
ldr r7,[sp,#4] @ tp[1]
mov r11,#0
umlal r10,r11,r5,r2 @ ap[0]*bp[i]+tp[0]
str r4,[r0,#13*4] @ save bp
mul r8,r10,r8
mov r12,#0
umlal r10,r12,r6,r8 @ np[0]*n0+"tp[0]"
mov r4,sp
.Linner:
ldr r5,[r1],#4 @ ap[j],ap++
adds r10,r11,r7 @ +=tp[j]
ldr r6,[r3],#4 @ np[j],np++
mov r11,#0
umlal r10,r11,r5,r2 @ ap[j]*bp[i]
mov r14,#0
umlal r12,r14,r6,r8 @ np[j]*n0
adc r11,r11,#0
ldr r7,[r4,#8] @ tp[j+1]
adds r12,r12,r10
str r12,[r4],#4 @ tp[j-1]=,tp++
adc r12,r14,#0
cmp r4,r0
bne .Linner
adds r12,r12,r11
mov r14,#0
ldr r4,[r0,#13*4] @ restore bp
adc r14,r14,#0
ldr r8,[r0,#14*4] @ restore n0
adds r12,r12,r7
ldr r7,[r0,#15*4] @ restore &bp[num]
adc r14,r14,#0
str r12,[r0] @ tp[num-1]=
str r14,[r0,#4] @ tp[num]=
cmp r4,r7
bne .Louter
ldr r2,[r0,#12*4] @ pull rp
add r0,r0,#4 @ r0 to point at &tp[num]
sub r5,r0,sp @ "original" num value
mov r4,sp @ "rewind" r4
mov r1,r4 @ "borrow" r1
sub r3,r3,r5 @ "rewind" r3 to &np[0]
subs r7,r7,r7 @ "clear" carry flag
.Lsub: ldr r7,[r4],#4
ldr r6,[r3],#4
sbcs r7,r7,r6 @ tp[j]-np[j]
str r7,[r2],#4 @ rp[j]=
teq r4,r0 @ preserve carry
bne .Lsub
sbcs r14,r14,#0 @ upmost carry
mov r4,sp @ "rewind" r4
sub r2,r2,r5 @ "rewind" r2
and r1,r4,r14
bic r3,r2,r14
orr r1,r1,r3 @ ap=borrow?tp:rp
.Lcopy: ldr r7,[r1],#4 @ copy or in-place refresh
str sp,[r4],#4 @ zap tp
str r7,[r2],#4
cmp r4,r0
bne .Lcopy
add sp,r0,#4 @ skip over tp[num+1]
ldmia sp!,{r4,r5,r6,r7,r8,r9,r10,r11,r12,lr} @ restore registers
add sp,sp,#2*4 @ skip over {r0,r2}
mov r0,#1
.Labrt:
#if __ARM_ARCH__>=5
bx lr @ .word 0xe12fff1e
#else
tst lr,#1
moveq pc,lr @ be binary compatible with V4, yet
.word 0xe12fff1e @ interoperable with Thumb ISA:-)
#endif
.size bn_mul_mont,.-bn_mul_mont
#if __ARM_MAX_ARCH__>=7
.arch armv7-a
.fpu neon
.type bn_mul8x_mont_neon,%function
.align 5
bn_mul8x_mont_neon:
mov ip,sp
stmdb sp!,{r4,r5,r6,r7,r8,r9,r10,r11}
vstmdb sp!,{d8,d9,d10,d11,d12,d13,d14,d15} @ ABI specification says so
ldmia ip,{r4,r5} @ load rest of parameter block
sub r7,sp,#16
vld1.32 {d28[0]}, [r2,:32]!
sub r7,r7,r5,lsl#4
vld1.32 {d0,d1,d2,d3}, [r1]! @ can't specify :32 :-(
and r7,r7,#-64
vld1.32 {d30[0]}, [r4,:32]
mov sp,r7 @ alloca
veor d8,d8,d8
subs r8,r5,#8
vzip.16 d28,d8
vmull.u32 q6,d28,d0[0]
vmull.u32 q7,d28,d0[1]
vmull.u32 q8,d28,d1[0]
vshl.i64 d10,d13,#16
vmull.u32 q9,d28,d1[1]
vadd.u64 d10,d10,d12
veor d8,d8,d8
vmul.u32 d29,d10,d30
vmull.u32 q10,d28,d2[0]
vld1.32 {d4,d5,d6,d7}, [r3]!
vmull.u32 q11,d28,d2[1]
vmull.u32 q12,d28,d3[0]
vzip.16 d29,d8
vmull.u32 q13,d28,d3[1]
bne .LNEON_1st
@ special case for num=8, everything is in register bank...
vmlal.u32 q6,d29,d4[0]
sub r9,r5,#1
vmlal.u32 q7,d29,d4[1]
vmlal.u32 q8,d29,d5[0]
vmlal.u32 q9,d29,d5[1]
vmlal.u32 q10,d29,d6[0]
vmov q5,q6
vmlal.u32 q11,d29,d6[1]
vmov q6,q7
vmlal.u32 q12,d29,d7[0]
vmov q7,q8
vmlal.u32 q13,d29,d7[1]
vmov q8,q9
vmov q9,q10
vshr.u64 d10,d10,#16
vmov q10,q11
vmov q11,q12
vadd.u64 d10,d10,d11
vmov q12,q13
veor q13,q13
vshr.u64 d10,d10,#16
b .LNEON_outer8
.align 4
.LNEON_outer8:
vld1.32 {d28[0]}, [r2,:32]!
veor d8,d8,d8
vzip.16 d28,d8
vadd.u64 d12,d12,d10
vmlal.u32 q6,d28,d0[0]
vmlal.u32 q7,d28,d0[1]
vmlal.u32 q8,d28,d1[0]
vshl.i64 d10,d13,#16
vmlal.u32 q9,d28,d1[1]
vadd.u64 d10,d10,d12
veor d8,d8,d8
subs r9,r9,#1
vmul.u32 d29,d10,d30
vmlal.u32 q10,d28,d2[0]
vmlal.u32 q11,d28,d2[1]
vmlal.u32 q12,d28,d3[0]
vzip.16 d29,d8
vmlal.u32 q13,d28,d3[1]
vmlal.u32 q6,d29,d4[0]
vmlal.u32 q7,d29,d4[1]
vmlal.u32 q8,d29,d5[0]
vmlal.u32 q9,d29,d5[1]
vmlal.u32 q10,d29,d6[0]
vmov q5,q6
vmlal.u32 q11,d29,d6[1]
vmov q6,q7
vmlal.u32 q12,d29,d7[0]
vmov q7,q8
vmlal.u32 q13,d29,d7[1]
vmov q8,q9
vmov q9,q10
vshr.u64 d10,d10,#16
vmov q10,q11
vmov q11,q12
vadd.u64 d10,d10,d11
vmov q12,q13
veor q13,q13
vshr.u64 d10,d10,#16
bne .LNEON_outer8
vadd.u64 d12,d12,d10
mov r7,sp
vshr.u64 d10,d12,#16
mov r8,r5
vadd.u64 d13,d13,d10
add r6,sp,#16
vshr.u64 d10,d13,#16
vzip.16 d12,d13
b .LNEON_tail2
.align 4
.LNEON_1st:
vmlal.u32 q6,d29,d4[0]
vld1.32 {d0,d1,d2,d3}, [r1]!
vmlal.u32 q7,d29,d4[1]
subs r8,r8,#8
vmlal.u32 q8,d29,d5[0]
vmlal.u32 q9,d29,d5[1]
vmlal.u32 q10,d29,d6[0]
vld1.32 {d4,d5}, [r3]!
vmlal.u32 q11,d29,d6[1]
vst1.64 {q6,q7}, [r7,:256]!
vmlal.u32 q12,d29,d7[0]
vmlal.u32 q13,d29,d7[1]
vst1.64 {q8,q9}, [r7,:256]!
vmull.u32 q6,d28,d0[0]
vld1.32 {d6,d7}, [r3]!
vmull.u32 q7,d28,d0[1]
vst1.64 {q10,q11}, [r7,:256]!
vmull.u32 q8,d28,d1[0]
vmull.u32 q9,d28,d1[1]
vst1.64 {q12,q13}, [r7,:256]!
vmull.u32 q10,d28,d2[0]
vmull.u32 q11,d28,d2[1]
vmull.u32 q12,d28,d3[0]
vmull.u32 q13,d28,d3[1]
bne .LNEON_1st
vmlal.u32 q6,d29,d4[0]
add r6,sp,#16
vmlal.u32 q7,d29,d4[1]
sub r1,r1,r5,lsl#2 @ rewind r1
vmlal.u32 q8,d29,d5[0]
vld1.64 {q5}, [sp,:128]
vmlal.u32 q9,d29,d5[1]
sub r9,r5,#1
vmlal.u32 q10,d29,d6[0]
vst1.64 {q6,q7}, [r7,:256]!
vmlal.u32 q11,d29,d6[1]
vshr.u64 d10,d10,#16
vld1.64 {q6}, [r6, :128]!
vmlal.u32 q12,d29,d7[0]
vst1.64 {q8,q9}, [r7,:256]!
vmlal.u32 q13,d29,d7[1]
vst1.64 {q10,q11}, [r7,:256]!
vadd.u64 d10,d10,d11
veor q4,q4,q4
vst1.64 {q12,q13}, [r7,:256]!
vld1.64 {q7,q8}, [r6, :256]!
vst1.64 {q4}, [r7,:128]
vshr.u64 d10,d10,#16
b .LNEON_outer
.align 4
.LNEON_outer:
vld1.32 {d28[0]}, [r2,:32]!
sub r3,r3,r5,lsl#2 @ rewind r3
vld1.32 {d0,d1,d2,d3}, [r1]!
veor d8,d8,d8
mov r7,sp
vzip.16 d28,d8
sub r8,r5,#8
vadd.u64 d12,d12,d10
vmlal.u32 q6,d28,d0[0]
vld1.64 {q9,q10},[r6,:256]!
vmlal.u32 q7,d28,d0[1]
vmlal.u32 q8,d28,d1[0]
vld1.64 {q11,q12},[r6,:256]!
vmlal.u32 q9,d28,d1[1]
vshl.i64 d10,d13,#16
veor d8,d8,d8
vadd.u64 d10,d10,d12
vld1.64 {q13},[r6,:128]!
vmul.u32 d29,d10,d30
vmlal.u32 q10,d28,d2[0]
vld1.32 {d4,d5,d6,d7}, [r3]!
vmlal.u32 q11,d28,d2[1]
vmlal.u32 q12,d28,d3[0]
vzip.16 d29,d8
vmlal.u32 q13,d28,d3[1]
.LNEON_inner:
vmlal.u32 q6,d29,d4[0]
vld1.32 {d0,d1,d2,d3}, [r1]!
vmlal.u32 q7,d29,d4[1]
subs r8,r8,#8
vmlal.u32 q8,d29,d5[0]
vmlal.u32 q9,d29,d5[1]
vst1.64 {q6,q7}, [r7,:256]!
vmlal.u32 q10,d29,d6[0]
vld1.64 {q6}, [r6, :128]!
vmlal.u32 q11,d29,d6[1]
vst1.64 {q8,q9}, [r7,:256]!
vmlal.u32 q12,d29,d7[0]
vld1.64 {q7,q8}, [r6, :256]!
vmlal.u32 q13,d29,d7[1]
vst1.64 {q10,q11}, [r7,:256]!
vmlal.u32 q6,d28,d0[0]
vld1.64 {q9,q10}, [r6, :256]!
vmlal.u32 q7,d28,d0[1]
vst1.64 {q12,q13}, [r7,:256]!
vmlal.u32 q8,d28,d1[0]
vld1.64 {q11,q12}, [r6, :256]!
vmlal.u32 q9,d28,d1[1]
vld1.32 {d4,d5,d6,d7}, [r3]!
vmlal.u32 q10,d28,d2[0]
vld1.64 {q13}, [r6, :128]!
vmlal.u32 q11,d28,d2[1]
vmlal.u32 q12,d28,d3[0]
vmlal.u32 q13,d28,d3[1]
bne .LNEON_inner
vmlal.u32 q6,d29,d4[0]
add r6,sp,#16
vmlal.u32 q7,d29,d4[1]
sub r1,r1,r5,lsl#2 @ rewind r1
vmlal.u32 q8,d29,d5[0]
vld1.64 {q5}, [sp,:128]
vmlal.u32 q9,d29,d5[1]
subs r9,r9,#1
vmlal.u32 q10,d29,d6[0]
vst1.64 {q6,q7}, [r7,:256]!
vmlal.u32 q11,d29,d6[1]
vld1.64 {q6}, [r6, :128]!
vshr.u64 d10,d10,#16
vst1.64 {q8,q9}, [r7,:256]!
vmlal.u32 q12,d29,d7[0]
vld1.64 {q7,q8}, [r6, :256]!
vmlal.u32 q13,d29,d7[1]
vst1.64 {q10,q11}, [r7,:256]!
vadd.u64 d10,d10,d11
vst1.64 {q12,q13}, [r7,:256]!
vshr.u64 d10,d10,#16
bne .LNEON_outer
mov r7,sp
mov r8,r5
.LNEON_tail:
vadd.u64 d12,d12,d10
vld1.64 {q9,q10}, [r6, :256]!
vshr.u64 d10,d12,#16
vadd.u64 d13,d13,d10
vld1.64 {q11,q12}, [r6, :256]!
vshr.u64 d10,d13,#16
vld1.64 {q13}, [r6, :128]!
vzip.16 d12,d13
.LNEON_tail2:
vadd.u64 d14,d14,d10
vst1.32 {d12[0]}, [r7, :32]!
vshr.u64 d10,d14,#16
vadd.u64 d15,d15,d10
vshr.u64 d10,d15,#16
vzip.16 d14,d15
vadd.u64 d16,d16,d10
vst1.32 {d14[0]}, [r7, :32]!
vshr.u64 d10,d16,#16
vadd.u64 d17,d17,d10
vshr.u64 d10,d17,#16
vzip.16 d16,d17
vadd.u64 d18,d18,d10
vst1.32 {d16[0]}, [r7, :32]!
vshr.u64 d10,d18,#16
vadd.u64 d19,d19,d10
vshr.u64 d10,d19,#16
vzip.16 d18,d19
vadd.u64 d20,d20,d10
vst1.32 {d18[0]}, [r7, :32]!
vshr.u64 d10,d20,#16
vadd.u64 d21,d21,d10
vshr.u64 d10,d21,#16
vzip.16 d20,d21
vadd.u64 d22,d22,d10
vst1.32 {d20[0]}, [r7, :32]!
vshr.u64 d10,d22,#16
vadd.u64 d23,d23,d10
vshr.u64 d10,d23,#16
vzip.16 d22,d23
vadd.u64 d24,d24,d10
vst1.32 {d22[0]}, [r7, :32]!
vshr.u64 d10,d24,#16
vadd.u64 d25,d25,d10
vld1.64 {q6}, [r6, :128]!
vshr.u64 d10,d25,#16
vzip.16 d24,d25
vadd.u64 d26,d26,d10
vst1.32 {d24[0]}, [r7, :32]!
vshr.u64 d10,d26,#16
vadd.u64 d27,d27,d10
vld1.64 {q7,q8}, [r6, :256]!
vshr.u64 d10,d27,#16
vzip.16 d26,d27
subs r8,r8,#8
vst1.32 {d26[0]}, [r7, :32]!
bne .LNEON_tail
vst1.32 {d10[0]}, [r7, :32] @ top-most bit
sub r3,r3,r5,lsl#2 @ rewind r3
subs r1,sp,#0 @ clear carry flag
add r2,sp,r5,lsl#2
.LNEON_sub:
ldmia r1!, {r4,r5,r6,r7}
ldmia r3!, {r8,r9,r10,r11}
sbcs r8, r4,r8
sbcs r9, r5,r9
sbcs r10,r6,r10
sbcs r11,r7,r11
teq r1,r2 @ preserves carry
stmia r0!, {r8,r9,r10,r11}
bne .LNEON_sub
ldr r10, [r1] @ load top-most bit
veor q0,q0,q0
sub r11,r2,sp @ this is num*4
veor q1,q1,q1
mov r1,sp
sub r0,r0,r11 @ rewind r0
mov r3,r2 @ second 3/4th of frame
sbcs r10,r10,#0 @ result is carry flag
.LNEON_copy_n_zap:
ldmia r1!, {r4,r5,r6,r7}
ldmia r0, {r8,r9,r10,r11}
movcc r8, r4
vst1.64 {q0,q1}, [r3,:256]! @ wipe
movcc r9, r5
movcc r10,r6
vst1.64 {q0,q1}, [r3,:256]! @ wipe
movcc r11,r7
ldmia r1, {r4,r5,r6,r7}
stmia r0!, {r8,r9,r10,r11}
sub r1,r1,#16
ldmia r0, {r8,r9,r10,r11}
movcc r8, r4
vst1.64 {q0,q1}, [r1,:256]! @ wipe
movcc r9, r5
movcc r10,r6
vst1.64 {q0,q1}, [r3,:256]! @ wipe
movcc r11,r7
teq r1,r2 @ preserves carry
stmia r0!, {r8,r9,r10,r11}
bne .LNEON_copy_n_zap
sub sp,ip,#96
vldmia sp!,{d8,d9,d10,d11,d12,d13,d14,d15}
ldmia sp!,{r4,r5,r6,r7,r8,r9,r10,r11}
bx lr @ .word 0xe12fff1e
.size bn_mul8x_mont_neon,.-bn_mul8x_mont_neon
#endif
.byte 77,111,110,116,103,111,109,101,114,121,32,109,117,108,116,105,112,108,105,99,97,116,105,111,110,32,102,111,114,32,65,82,77,118,52,47,78,69,79,78,44,32,67,82,89,80,84,79,71,65,77,83,32,98,121,32,60,97,112,112,114,111,64,111,112,101,110,115,115,108,46,111,114,103,62,0
.align 2
.align 2
#if __ARM_MAX_ARCH__>=7
.comm OPENSSL_armcap_P,4,4
.hidden OPENSSL_armcap_P
#endif
#endif

View File

@ -0,0 +1,541 @@
#if defined(__arm__)
#if defined(__arm__)
#include "arm_arch.h"
.syntax unified
.text
.code 32
#ifdef __APPLE__
#define ldrplb ldrbpl
#define ldrneb ldrbne
#endif
.type rem_4bit,%object
.align 5
rem_4bit:
.short 0x0000,0x1C20,0x3840,0x2460
.short 0x7080,0x6CA0,0x48C0,0x54E0
.short 0xE100,0xFD20,0xD940,0xC560
.short 0x9180,0x8DA0,0xA9C0,0xB5E0
.size rem_4bit,.-rem_4bit
.type rem_4bit_get,%function
rem_4bit_get:
sub r2,pc,#8
sub r2,r2,#32 @ &rem_4bit
b .Lrem_4bit_got
nop
.size rem_4bit_get,.-rem_4bit_get
.globl gcm_ghash_4bit
.hidden gcm_ghash_4bit
.type gcm_ghash_4bit,%function
gcm_ghash_4bit:
sub r12,pc,#8
add r3,r2,r3 @ r3 to point at the end
stmdb sp!,{r3,r4,r5,r6,r7,r8,r9,r10,r11,lr} @ save r3/end too
sub r12,r12,#48 @ &rem_4bit
ldmia r12,{r4,r5,r6,r7,r8,r9,r10,r11} @ copy rem_4bit ...
stmdb sp!,{r4,r5,r6,r7,r8,r9,r10,r11} @ ... to stack
ldrb r12,[r2,#15]
ldrb r14,[r0,#15]
.Louter:
eor r12,r12,r14
and r14,r12,#0xf0
and r12,r12,#0x0f
mov r3,#14
add r7,r1,r12,lsl#4
ldmia r7,{r4,r5,r6,r7} @ load Htbl[nlo]
add r11,r1,r14
ldrb r12,[r2,#14]
and r14,r4,#0xf @ rem
ldmia r11,{r8,r9,r10,r11} @ load Htbl[nhi]
add r14,r14,r14
eor r4,r8,r4,lsr#4
ldrh r8,[sp,r14] @ rem_4bit[rem]
eor r4,r4,r5,lsl#28
ldrb r14,[r0,#14]
eor r5,r9,r5,lsr#4
eor r5,r5,r6,lsl#28
eor r6,r10,r6,lsr#4
eor r6,r6,r7,lsl#28
eor r7,r11,r7,lsr#4
eor r12,r12,r14
and r14,r12,#0xf0
and r12,r12,#0x0f
eor r7,r7,r8,lsl#16
.Linner:
add r11,r1,r12,lsl#4
and r12,r4,#0xf @ rem
subs r3,r3,#1
add r12,r12,r12
ldmia r11,{r8,r9,r10,r11} @ load Htbl[nlo]
eor r4,r8,r4,lsr#4
eor r4,r4,r5,lsl#28
eor r5,r9,r5,lsr#4
eor r5,r5,r6,lsl#28
ldrh r8,[sp,r12] @ rem_4bit[rem]
eor r6,r10,r6,lsr#4
ldrbpl r12,[r2,r3]
eor r6,r6,r7,lsl#28
eor r7,r11,r7,lsr#4
add r11,r1,r14
and r14,r4,#0xf @ rem
eor r7,r7,r8,lsl#16 @ ^= rem_4bit[rem]
add r14,r14,r14
ldmia r11,{r8,r9,r10,r11} @ load Htbl[nhi]
eor r4,r8,r4,lsr#4
ldrbpl r8,[r0,r3]
eor r4,r4,r5,lsl#28
eor r5,r9,r5,lsr#4
ldrh r9,[sp,r14]
eor r5,r5,r6,lsl#28
eor r6,r10,r6,lsr#4
eor r6,r6,r7,lsl#28
eorpl r12,r12,r8
eor r7,r11,r7,lsr#4
andpl r14,r12,#0xf0
andpl r12,r12,#0x0f
eor r7,r7,r9,lsl#16 @ ^= rem_4bit[rem]
bpl .Linner
ldr r3,[sp,#32] @ re-load r3/end
add r2,r2,#16
mov r14,r4
#if __ARM_ARCH__>=7 && defined(__ARMEL__)
rev r4,r4
str r4,[r0,#12]
#elif defined(__ARMEB__)
str r4,[r0,#12]
#else
mov r9,r4,lsr#8
strb r4,[r0,#12+3]
mov r10,r4,lsr#16
strb r9,[r0,#12+2]
mov r11,r4,lsr#24
strb r10,[r0,#12+1]
strb r11,[r0,#12]
#endif
cmp r2,r3
#if __ARM_ARCH__>=7 && defined(__ARMEL__)
rev r5,r5
str r5,[r0,#8]
#elif defined(__ARMEB__)
str r5,[r0,#8]
#else
mov r9,r5,lsr#8
strb r5,[r0,#8+3]
mov r10,r5,lsr#16
strb r9,[r0,#8+2]
mov r11,r5,lsr#24
strb r10,[r0,#8+1]
strb r11,[r0,#8]
#endif
ldrbne r12,[r2,#15]
#if __ARM_ARCH__>=7 && defined(__ARMEL__)
rev r6,r6
str r6,[r0,#4]
#elif defined(__ARMEB__)
str r6,[r0,#4]
#else
mov r9,r6,lsr#8
strb r6,[r0,#4+3]
mov r10,r6,lsr#16
strb r9,[r0,#4+2]
mov r11,r6,lsr#24
strb r10,[r0,#4+1]
strb r11,[r0,#4]
#endif
#if __ARM_ARCH__>=7 && defined(__ARMEL__)
rev r7,r7
str r7,[r0,#0]
#elif defined(__ARMEB__)
str r7,[r0,#0]
#else
mov r9,r7,lsr#8
strb r7,[r0,#0+3]
mov r10,r7,lsr#16
strb r9,[r0,#0+2]
mov r11,r7,lsr#24
strb r10,[r0,#0+1]
strb r11,[r0,#0]
#endif
bne .Louter
add sp,sp,#36
#if __ARM_ARCH__>=5
ldmia sp!,{r4,r5,r6,r7,r8,r9,r10,r11,pc}
#else
ldmia sp!,{r4,r5,r6,r7,r8,r9,r10,r11,lr}
tst lr,#1
moveq pc,lr @ be binary compatible with V4, yet
.word 0xe12fff1e @ interoperable with Thumb ISA:-)
#endif
.size gcm_ghash_4bit,.-gcm_ghash_4bit
.globl gcm_gmult_4bit
.hidden gcm_gmult_4bit
.type gcm_gmult_4bit,%function
gcm_gmult_4bit:
stmdb sp!,{r4,r5,r6,r7,r8,r9,r10,r11,lr}
ldrb r12,[r0,#15]
b rem_4bit_get
.Lrem_4bit_got:
and r14,r12,#0xf0
and r12,r12,#0x0f
mov r3,#14
add r7,r1,r12,lsl#4
ldmia r7,{r4,r5,r6,r7} @ load Htbl[nlo]
ldrb r12,[r0,#14]
add r11,r1,r14
and r14,r4,#0xf @ rem
ldmia r11,{r8,r9,r10,r11} @ load Htbl[nhi]
add r14,r14,r14
eor r4,r8,r4,lsr#4
ldrh r8,[r2,r14] @ rem_4bit[rem]
eor r4,r4,r5,lsl#28
eor r5,r9,r5,lsr#4
eor r5,r5,r6,lsl#28
eor r6,r10,r6,lsr#4
eor r6,r6,r7,lsl#28
eor r7,r11,r7,lsr#4
and r14,r12,#0xf0
eor r7,r7,r8,lsl#16
and r12,r12,#0x0f
.Loop:
add r11,r1,r12,lsl#4
and r12,r4,#0xf @ rem
subs r3,r3,#1
add r12,r12,r12
ldmia r11,{r8,r9,r10,r11} @ load Htbl[nlo]
eor r4,r8,r4,lsr#4
eor r4,r4,r5,lsl#28
eor r5,r9,r5,lsr#4
eor r5,r5,r6,lsl#28
ldrh r8,[r2,r12] @ rem_4bit[rem]
eor r6,r10,r6,lsr#4
ldrbpl r12,[r0,r3]
eor r6,r6,r7,lsl#28
eor r7,r11,r7,lsr#4
add r11,r1,r14
and r14,r4,#0xf @ rem
eor r7,r7,r8,lsl#16 @ ^= rem_4bit[rem]
add r14,r14,r14
ldmia r11,{r8,r9,r10,r11} @ load Htbl[nhi]
eor r4,r8,r4,lsr#4
eor r4,r4,r5,lsl#28
eor r5,r9,r5,lsr#4
ldrh r8,[r2,r14] @ rem_4bit[rem]
eor r5,r5,r6,lsl#28
eor r6,r10,r6,lsr#4
eor r6,r6,r7,lsl#28
eor r7,r11,r7,lsr#4
andpl r14,r12,#0xf0
andpl r12,r12,#0x0f
eor r7,r7,r8,lsl#16 @ ^= rem_4bit[rem]
bpl .Loop
#if __ARM_ARCH__>=7 && defined(__ARMEL__)
rev r4,r4
str r4,[r0,#12]
#elif defined(__ARMEB__)
str r4,[r0,#12]
#else
mov r9,r4,lsr#8
strb r4,[r0,#12+3]
mov r10,r4,lsr#16
strb r9,[r0,#12+2]
mov r11,r4,lsr#24
strb r10,[r0,#12+1]
strb r11,[r0,#12]
#endif
#if __ARM_ARCH__>=7 && defined(__ARMEL__)
rev r5,r5
str r5,[r0,#8]
#elif defined(__ARMEB__)
str r5,[r0,#8]
#else
mov r9,r5,lsr#8
strb r5,[r0,#8+3]
mov r10,r5,lsr#16
strb r9,[r0,#8+2]
mov r11,r5,lsr#24
strb r10,[r0,#8+1]
strb r11,[r0,#8]
#endif
#if __ARM_ARCH__>=7 && defined(__ARMEL__)
rev r6,r6
str r6,[r0,#4]
#elif defined(__ARMEB__)
str r6,[r0,#4]
#else
mov r9,r6,lsr#8
strb r6,[r0,#4+3]
mov r10,r6,lsr#16
strb r9,[r0,#4+2]
mov r11,r6,lsr#24
strb r10,[r0,#4+1]
strb r11,[r0,#4]
#endif
#if __ARM_ARCH__>=7 && defined(__ARMEL__)
rev r7,r7
str r7,[r0,#0]
#elif defined(__ARMEB__)
str r7,[r0,#0]
#else
mov r9,r7,lsr#8
strb r7,[r0,#0+3]
mov r10,r7,lsr#16
strb r9,[r0,#0+2]
mov r11,r7,lsr#24
strb r10,[r0,#0+1]
strb r11,[r0,#0]
#endif
#if __ARM_ARCH__>=5
ldmia sp!,{r4,r5,r6,r7,r8,r9,r10,r11,pc}
#else
ldmia sp!,{r4,r5,r6,r7,r8,r9,r10,r11,lr}
tst lr,#1
moveq pc,lr @ be binary compatible with V4, yet
.word 0xe12fff1e @ interoperable with Thumb ISA:-)
#endif
.size gcm_gmult_4bit,.-gcm_gmult_4bit
#if __ARM_MAX_ARCH__>=7
.arch armv7-a
.fpu neon
.globl gcm_init_neon
.hidden gcm_init_neon
.type gcm_init_neon,%function
.align 4
gcm_init_neon:
vld1.64 d7,[r1]! @ load H
vmov.i8 q8,#0xe1
vld1.64 d6,[r1]
vshl.i64 d17,#57
vshr.u64 d16,#63 @ t0=0xc2....01
vdup.8 q9,d7[7]
vshr.u64 d26,d6,#63
vshr.s8 q9,#7 @ broadcast carry bit
vshl.i64 q3,q3,#1
vand q8,q8,q9
vorr d7,d26 @ H<<<=1
veor q3,q3,q8 @ twisted H
vstmia r0,{q3}
bx lr @ bx lr
.size gcm_init_neon,.-gcm_init_neon
.globl gcm_gmult_neon
.hidden gcm_gmult_neon
.type gcm_gmult_neon,%function
.align 4
gcm_gmult_neon:
vld1.64 d7,[r0]! @ load Xi
vld1.64 d6,[r0]!
vmov.i64 d29,#0x0000ffffffffffff
vldmia r1,{d26,d27} @ load twisted H
vmov.i64 d30,#0x00000000ffffffff
#ifdef __ARMEL__
vrev64.8 q3,q3
#endif
vmov.i64 d31,#0x000000000000ffff
veor d28,d26,d27 @ Karatsuba pre-processing
mov r3,#16
b .Lgmult_neon
.size gcm_gmult_neon,.-gcm_gmult_neon
.globl gcm_ghash_neon
.hidden gcm_ghash_neon
.type gcm_ghash_neon,%function
.align 4
gcm_ghash_neon:
vld1.64 d1,[r0]! @ load Xi
vld1.64 d0,[r0]!
vmov.i64 d29,#0x0000ffffffffffff
vldmia r1,{d26,d27} @ load twisted H
vmov.i64 d30,#0x00000000ffffffff
#ifdef __ARMEL__
vrev64.8 q0,q0
#endif
vmov.i64 d31,#0x000000000000ffff
veor d28,d26,d27 @ Karatsuba pre-processing
.Loop_neon:
vld1.64 d7,[r2]! @ load inp
vld1.64 d6,[r2]!
#ifdef __ARMEL__
vrev64.8 q3,q3
#endif
veor q3,q0 @ inp^=Xi
.Lgmult_neon:
vext.8 d16, d26, d26, #1 @ A1
vmull.p8 q8, d16, d6 @ F = A1*B
vext.8 d0, d6, d6, #1 @ B1
vmull.p8 q0, d26, d0 @ E = A*B1
vext.8 d18, d26, d26, #2 @ A2
vmull.p8 q9, d18, d6 @ H = A2*B
vext.8 d22, d6, d6, #2 @ B2
vmull.p8 q11, d26, d22 @ G = A*B2
vext.8 d20, d26, d26, #3 @ A3
veor q8, q8, q0 @ L = E + F
vmull.p8 q10, d20, d6 @ J = A3*B
vext.8 d0, d6, d6, #3 @ B3
veor q9, q9, q11 @ M = G + H
vmull.p8 q0, d26, d0 @ I = A*B3
veor d16, d16, d17 @ t0 = (L) (P0 + P1) << 8
vand d17, d17, d29
vext.8 d22, d6, d6, #4 @ B4
veor d18, d18, d19 @ t1 = (M) (P2 + P3) << 16
vand d19, d19, d30
vmull.p8 q11, d26, d22 @ K = A*B4
veor q10, q10, q0 @ N = I + J
veor d16, d16, d17
veor d18, d18, d19
veor d20, d20, d21 @ t2 = (N) (P4 + P5) << 24
vand d21, d21, d31
vext.8 q8, q8, q8, #15
veor d22, d22, d23 @ t3 = (K) (P6 + P7) << 32
vmov.i64 d23, #0
vext.8 q9, q9, q9, #14
veor d20, d20, d21
vmull.p8 q0, d26, d6 @ D = A*B
vext.8 q11, q11, q11, #12
vext.8 q10, q10, q10, #13
veor q8, q8, q9
veor q10, q10, q11
veor q0, q0, q8
veor q0, q0, q10
veor d6,d6,d7 @ Karatsuba pre-processing
vext.8 d16, d28, d28, #1 @ A1
vmull.p8 q8, d16, d6 @ F = A1*B
vext.8 d2, d6, d6, #1 @ B1
vmull.p8 q1, d28, d2 @ E = A*B1
vext.8 d18, d28, d28, #2 @ A2
vmull.p8 q9, d18, d6 @ H = A2*B
vext.8 d22, d6, d6, #2 @ B2
vmull.p8 q11, d28, d22 @ G = A*B2
vext.8 d20, d28, d28, #3 @ A3
veor q8, q8, q1 @ L = E + F
vmull.p8 q10, d20, d6 @ J = A3*B
vext.8 d2, d6, d6, #3 @ B3
veor q9, q9, q11 @ M = G + H
vmull.p8 q1, d28, d2 @ I = A*B3
veor d16, d16, d17 @ t0 = (L) (P0 + P1) << 8
vand d17, d17, d29
vext.8 d22, d6, d6, #4 @ B4
veor d18, d18, d19 @ t1 = (M) (P2 + P3) << 16
vand d19, d19, d30
vmull.p8 q11, d28, d22 @ K = A*B4
veor q10, q10, q1 @ N = I + J
veor d16, d16, d17
veor d18, d18, d19
veor d20, d20, d21 @ t2 = (N) (P4 + P5) << 24
vand d21, d21, d31
vext.8 q8, q8, q8, #15
veor d22, d22, d23 @ t3 = (K) (P6 + P7) << 32
vmov.i64 d23, #0
vext.8 q9, q9, q9, #14
veor d20, d20, d21
vmull.p8 q1, d28, d6 @ D = A*B
vext.8 q11, q11, q11, #12
vext.8 q10, q10, q10, #13
veor q8, q8, q9
veor q10, q10, q11
veor q1, q1, q8
veor q1, q1, q10
vext.8 d16, d27, d27, #1 @ A1
vmull.p8 q8, d16, d7 @ F = A1*B
vext.8 d4, d7, d7, #1 @ B1
vmull.p8 q2, d27, d4 @ E = A*B1
vext.8 d18, d27, d27, #2 @ A2
vmull.p8 q9, d18, d7 @ H = A2*B
vext.8 d22, d7, d7, #2 @ B2
vmull.p8 q11, d27, d22 @ G = A*B2
vext.8 d20, d27, d27, #3 @ A3
veor q8, q8, q2 @ L = E + F
vmull.p8 q10, d20, d7 @ J = A3*B
vext.8 d4, d7, d7, #3 @ B3
veor q9, q9, q11 @ M = G + H
vmull.p8 q2, d27, d4 @ I = A*B3
veor d16, d16, d17 @ t0 = (L) (P0 + P1) << 8
vand d17, d17, d29
vext.8 d22, d7, d7, #4 @ B4
veor d18, d18, d19 @ t1 = (M) (P2 + P3) << 16
vand d19, d19, d30
vmull.p8 q11, d27, d22 @ K = A*B4
veor q10, q10, q2 @ N = I + J
veor d16, d16, d17
veor d18, d18, d19
veor d20, d20, d21 @ t2 = (N) (P4 + P5) << 24
vand d21, d21, d31
vext.8 q8, q8, q8, #15
veor d22, d22, d23 @ t3 = (K) (P6 + P7) << 32
vmov.i64 d23, #0
vext.8 q9, q9, q9, #14
veor d20, d20, d21
vmull.p8 q2, d27, d7 @ D = A*B
vext.8 q11, q11, q11, #12
vext.8 q10, q10, q10, #13
veor q8, q8, q9
veor q10, q10, q11
veor q2, q2, q8
veor q2, q2, q10
veor q1,q1,q0 @ Karatsuba post-processing
veor q1,q1,q2
veor d1,d1,d2
veor d4,d4,d3 @ Xh|Xl - 256-bit result
@ equivalent of reduction_avx from ghash-x86_64.pl
vshl.i64 q9,q0,#57 @ 1st phase
vshl.i64 q10,q0,#62
veor q10,q10,q9 @
vshl.i64 q9,q0,#63
veor q10, q10, q9 @
veor d1,d1,d20 @
veor d4,d4,d21
vshr.u64 q10,q0,#1 @ 2nd phase
veor q2,q2,q0
veor q0,q0,q10 @
vshr.u64 q10,q10,#6
vshr.u64 q0,q0,#1 @
veor q0,q0,q2 @
veor q0,q0,q10 @
subs r3,#16
bne .Loop_neon
#ifdef __ARMEL__
vrev64.8 q0,q0
#endif
sub r0,#16
vst1.64 d1,[r0]! @ write out Xi
vst1.64 d0,[r0]
bx lr @ bx lr
.size gcm_ghash_neon,.-gcm_ghash_neon
#endif
.byte 71,72,65,83,72,32,102,111,114,32,65,82,77,118,52,47,78,69,79,78,44,32,67,82,89,80,84,79,71,65,77,83,32,98,121,32,60,97,112,112,114,111,64,111,112,101,110,115,115,108,46,111,114,103,62,0
.align 2
.align 2
#endif
#endif

View File

@ -0,0 +1,233 @@
#if defined(__arm__)
#include "arm_arch.h"
.text
.fpu neon
.code 32
.globl gcm_init_v8
.type gcm_init_v8,%function
.align 4
gcm_init_v8:
vld1.64 {q9},[r1] @ load input H
vmov.i8 q11,#0xe1
vshl.i64 q11,q11,#57 @ 0xc2.0
vext.8 q3,q9,q9,#8
vshr.u64 q10,q11,#63
vdup.32 q9,d18[1]
vext.8 q8,q10,q11,#8 @ t0=0xc2....01
vshr.u64 q10,q3,#63
vshr.s32 q9,q9,#31 @ broadcast carry bit
vand q10,q10,q8
vshl.i64 q3,q3,#1
vext.8 q10,q10,q10,#8
vand q8,q8,q9
vorr q3,q3,q10 @ H<<<=1
veor q12,q3,q8 @ twisted H
vst1.64 {q12},[r0]! @ store Htable[0]
@ calculate H^2
vext.8 q8,q12,q12,#8 @ Karatsuba pre-processing
.byte 0xa8,0x0e,0xa8,0xf2 @ pmull q0,q12,q12
veor q8,q8,q12
.byte 0xa9,0x4e,0xa9,0xf2 @ pmull2 q2,q12,q12
.byte 0xa0,0x2e,0xa0,0xf2 @ pmull q1,q8,q8
vext.8 q9,q0,q2,#8 @ Karatsuba post-processing
veor q10,q0,q2
veor q1,q1,q9
veor q1,q1,q10
.byte 0x26,0x4e,0xe0,0xf2 @ pmull q10,q0,q11 @ 1st phase
vmov d4,d3 @ Xh|Xm - 256-bit result
vmov d3,d0 @ Xm is rotated Xl
veor q0,q1,q10
vext.8 q10,q0,q0,#8 @ 2nd phase
.byte 0x26,0x0e,0xa0,0xf2 @ pmull q0,q0,q11
veor q10,q10,q2
veor q14,q0,q10
vext.8 q9,q14,q14,#8 @ Karatsuba pre-processing
veor q9,q9,q14
vext.8 q13,q8,q9,#8 @ pack Karatsuba pre-processed
vst1.64 {q13,q14},[r0] @ store Htable[1..2]
bx lr
.size gcm_init_v8,.-gcm_init_v8
.globl gcm_gmult_v8
.type gcm_gmult_v8,%function
.align 4
gcm_gmult_v8:
vld1.64 {q9},[r0] @ load Xi
vmov.i8 q11,#0xe1
vld1.64 {q12,q13},[r1] @ load twisted H, ...
vshl.u64 q11,q11,#57
#ifndef __ARMEB__
vrev64.8 q9,q9
#endif
vext.8 q3,q9,q9,#8
.byte 0x86,0x0e,0xa8,0xf2 @ pmull q0,q12,q3 @ H.lo·Xi.lo
veor q9,q9,q3 @ Karatsuba pre-processing
.byte 0x87,0x4e,0xa9,0xf2 @ pmull2 q2,q12,q3 @ H.hi·Xi.hi
.byte 0xa2,0x2e,0xaa,0xf2 @ pmull q1,q13,q9 @ (H.lo+H.hi)·(Xi.lo+Xi.hi)
vext.8 q9,q0,q2,#8 @ Karatsuba post-processing
veor q10,q0,q2
veor q1,q1,q9
veor q1,q1,q10
.byte 0x26,0x4e,0xe0,0xf2 @ pmull q10,q0,q11 @ 1st phase of reduction
vmov d4,d3 @ Xh|Xm - 256-bit result
vmov d3,d0 @ Xm is rotated Xl
veor q0,q1,q10
vext.8 q10,q0,q0,#8 @ 2nd phase of reduction
.byte 0x26,0x0e,0xa0,0xf2 @ pmull q0,q0,q11
veor q10,q10,q2
veor q0,q0,q10
#ifndef __ARMEB__
vrev64.8 q0,q0
#endif
vext.8 q0,q0,q0,#8
vst1.64 {q0},[r0] @ write out Xi
bx lr
.size gcm_gmult_v8,.-gcm_gmult_v8
.globl gcm_ghash_v8
.type gcm_ghash_v8,%function
.align 4
gcm_ghash_v8:
vstmdb sp!,{d8,d9,d10,d11,d12,d13,d14,d15} @ 32-bit ABI says so
vld1.64 {q0},[r0] @ load [rotated] Xi
@ "[rotated]" means that
@ loaded value would have
@ to be rotated in order to
@ make it appear as in
@ alorithm specification
subs r3,r3,#32 @ see if r3 is 32 or larger
mov r12,#16 @ r12 is used as post-
@ increment for input pointer;
@ as loop is modulo-scheduled
@ r12 is zeroed just in time
@ to preclude oversteping
@ inp[len], which means that
@ last block[s] are actually
@ loaded twice, but last
@ copy is not processed
vld1.64 {q12,q13},[r1]! @ load twisted H, ..., H^2
vmov.i8 q11,#0xe1
vld1.64 {q14},[r1]
moveq r12,#0 @ is it time to zero r12?
vext.8 q0,q0,q0,#8 @ rotate Xi
vld1.64 {q8},[r2]! @ load [rotated] I[0]
vshl.u64 q11,q11,#57 @ compose 0xc2.0 constant
#ifndef __ARMEB__
vrev64.8 q8,q8
vrev64.8 q0,q0
#endif
vext.8 q3,q8,q8,#8 @ rotate I[0]
blo .Lodd_tail_v8 @ r3 was less than 32
vld1.64 {q9},[r2],r12 @ load [rotated] I[1]
#ifndef __ARMEB__
vrev64.8 q9,q9
#endif
vext.8 q7,q9,q9,#8
veor q3,q3,q0 @ I[i]^=Xi
.byte 0x8e,0x8e,0xa8,0xf2 @ pmull q4,q12,q7 @ H·Ii+1
veor q9,q9,q7 @ Karatsuba pre-processing
.byte 0x8f,0xce,0xa9,0xf2 @ pmull2 q6,q12,q7
b .Loop_mod2x_v8
.align 4
.Loop_mod2x_v8:
vext.8 q10,q3,q3,#8
subs r3,r3,#32 @ is there more data?
.byte 0x86,0x0e,0xac,0xf2 @ pmull q0,q14,q3 @ H^2.lo·Xi.lo
movlo r12,#0 @ is it time to zero r12?
.byte 0xa2,0xae,0xaa,0xf2 @ pmull q5,q13,q9
veor q10,q10,q3 @ Karatsuba pre-processing
.byte 0x87,0x4e,0xad,0xf2 @ pmull2 q2,q14,q3 @ H^2.hi·Xi.hi
veor q0,q0,q4 @ accumulate
.byte 0xa5,0x2e,0xab,0xf2 @ pmull2 q1,q13,q10 @ (H^2.lo+H^2.hi)·(Xi.lo+Xi.hi)
vld1.64 {q8},[r2],r12 @ load [rotated] I[i+2]
veor q2,q2,q6
moveq r12,#0 @ is it time to zero r12?
veor q1,q1,q5
vext.8 q9,q0,q2,#8 @ Karatsuba post-processing
veor q10,q0,q2
veor q1,q1,q9
vld1.64 {q9},[r2],r12 @ load [rotated] I[i+3]
#ifndef __ARMEB__
vrev64.8 q8,q8
#endif
veor q1,q1,q10
.byte 0x26,0x4e,0xe0,0xf2 @ pmull q10,q0,q11 @ 1st phase of reduction
#ifndef __ARMEB__
vrev64.8 q9,q9
#endif
vmov d4,d3 @ Xh|Xm - 256-bit result
vmov d3,d0 @ Xm is rotated Xl
vext.8 q7,q9,q9,#8
vext.8 q3,q8,q8,#8
veor q0,q1,q10
.byte 0x8e,0x8e,0xa8,0xf2 @ pmull q4,q12,q7 @ H·Ii+1
veor q3,q3,q2 @ accumulate q3 early
vext.8 q10,q0,q0,#8 @ 2nd phase of reduction
.byte 0x26,0x0e,0xa0,0xf2 @ pmull q0,q0,q11
veor q3,q3,q10
veor q9,q9,q7 @ Karatsuba pre-processing
veor q3,q3,q0
.byte 0x8f,0xce,0xa9,0xf2 @ pmull2 q6,q12,q7
bhs .Loop_mod2x_v8 @ there was at least 32 more bytes
veor q2,q2,q10
vext.8 q3,q8,q8,#8 @ re-construct q3
adds r3,r3,#32 @ re-construct r3
veor q0,q0,q2 @ re-construct q0
beq .Ldone_v8 @ is r3 zero?
.Lodd_tail_v8:
vext.8 q10,q0,q0,#8
veor q3,q3,q0 @ inp^=Xi
veor q9,q8,q10 @ q9 is rotated inp^Xi
.byte 0x86,0x0e,0xa8,0xf2 @ pmull q0,q12,q3 @ H.lo·Xi.lo
veor q9,q9,q3 @ Karatsuba pre-processing
.byte 0x87,0x4e,0xa9,0xf2 @ pmull2 q2,q12,q3 @ H.hi·Xi.hi
.byte 0xa2,0x2e,0xaa,0xf2 @ pmull q1,q13,q9 @ (H.lo+H.hi)·(Xi.lo+Xi.hi)
vext.8 q9,q0,q2,#8 @ Karatsuba post-processing
veor q10,q0,q2
veor q1,q1,q9
veor q1,q1,q10
.byte 0x26,0x4e,0xe0,0xf2 @ pmull q10,q0,q11 @ 1st phase of reduction
vmov d4,d3 @ Xh|Xm - 256-bit result
vmov d3,d0 @ Xm is rotated Xl
veor q0,q1,q10
vext.8 q10,q0,q0,#8 @ 2nd phase of reduction
.byte 0x26,0x0e,0xa0,0xf2 @ pmull q0,q0,q11
veor q10,q10,q2
veor q0,q0,q10
.Ldone_v8:
#ifndef __ARMEB__
vrev64.8 q0,q0
#endif
vext.8 q0,q0,q0,#8
vst1.64 {q0},[r0] @ write out Xi
vldmia sp!,{d8,d9,d10,d11,d12,d13,d14,d15} @ 32-bit ABI says so
bx lr
.size gcm_ghash_v8,.-gcm_ghash_v8
.byte 71,72,65,83,72,32,102,111,114,32,65,82,77,118,56,44,32,67,82,89,80,84,79,71,65,77,83,32,98,121,32,60,97,112,112,114,111,64,111,112,101,110,115,115,108,46,111,114,103,62,0
.align 2
.align 2
#endif

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

Some files were not shown because too many files have changed in this diff Show More