1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129
|
//===----------------------------------------------------------------------===//
//
// This source file is part of the SwiftNIO open source project
//
// Copyright (c) 2017-2018 Apple Inc. and the SwiftNIO project authors
// Licensed under Apache License v2.0
//
// See LICENSE.txt for license information
// See CONTRIBUTORS.txt for the list of SwiftNIO project authors
//
// SPDX-License-Identifier: Apache-2.0
//
//===----------------------------------------------------------------------===//
import XCTest
#if compiler(>=5.1)
@_implementationOnly import CNIOBoringSSL
#else
import CNIOBoringSSL
#endif
import NIO
import NIOTLS
import NIOSSL
class NIOSSLALPNTest: XCTestCase {
static var cert: NIOSSLCertificate!
static var key: NIOSSLPrivateKey!
override class func setUp() {
super.setUp()
let (cert, key) = generateSelfSignedCert()
NIOSSLIntegrationTest.cert = cert
NIOSSLIntegrationTest.key = key
}
private func configuredSSLContextWithAlpnProtocols(protocols: [String]) throws -> NIOSSLContext {
var config = TLSConfiguration.makeServerConfiguration(
certificateChain: [.certificate(NIOSSLIntegrationTest.cert)],
privateKey: .privateKey(NIOSSLIntegrationTest.key)
)
config.trustRoots = .certificates([NIOSSLIntegrationTest.cert])
config.applicationProtocols = protocols
return try NIOSSLContext(configuration: config)
}
private func assertNegotiatedProtocol(protocol: String?,
serverContext: NIOSSLContext,
clientContext: NIOSSLContext) throws {
let group = MultiThreadedEventLoopGroup(numberOfThreads: 1)
defer {
XCTAssertNoThrow(try group.syncShutdownGracefully())
}
let completionPromise: EventLoopPromise<ByteBuffer> = group.next().makePromise()
let serverHandler = EventRecorderHandler<TLSUserEvent>()
let serverChannel = try serverTLSChannel(context: serverContext,
handlers: [serverHandler, PromiseOnReadHandler(promise: completionPromise)],
group: group)
defer {
XCTAssertNoThrow(try serverChannel.close().wait())
}
let clientChannel = try clientTLSChannel(context: clientContext,
preHandlers: [],
postHandlers: [],
group: group,
connectingTo: serverChannel.localAddress!)
defer {
XCTAssertNoThrow(try clientChannel.close().wait())
}
var originalBuffer = clientChannel.allocator.buffer(capacity: 5)
originalBuffer.writeString("Hello")
try clientChannel.writeAndFlush(originalBuffer).wait()
_ = try completionPromise.futureResult.wait()
let expectedEvents: [EventRecorderHandler<TLSUserEvent>.RecordedEvents] = [
.Registered,
.Active,
.UserEvent(TLSUserEvent.handshakeCompleted(negotiatedProtocol: `protocol`)),
.Read,
.ReadComplete
]
XCTAssertEqual(expectedEvents, serverHandler.events)
}
func testBasicALPNNegotiation() throws {
let context: NIOSSLContext
context = try assertNoThrowWithValue(configuredSSLContextWithAlpnProtocols(protocols: ["h2", "http/1.1"]))
XCTAssertNoThrow(try assertNegotiatedProtocol(protocol: "h2", serverContext: context, clientContext: context))
}
func testBasicALPNNegotiationPrefersServerPriority() throws {
let serverCtx: NIOSSLContext
let clientCtx: NIOSSLContext
serverCtx = try assertNoThrowWithValue(configuredSSLContextWithAlpnProtocols(protocols: ["h2", "http/1.1"]))
clientCtx = try assertNoThrowWithValue(configuredSSLContextWithAlpnProtocols(protocols: ["http/1.1", "h2"]))
XCTAssertNoThrow(try assertNegotiatedProtocol(protocol: "h2", serverContext: serverCtx, clientContext: clientCtx))
}
func testBasicALPNNegotiationNoOverlap() throws {
let serverCtx: NIOSSLContext
let clientCtx: NIOSSLContext
serverCtx = try assertNoThrowWithValue(configuredSSLContextWithAlpnProtocols(protocols: ["h2", "http/1.1"]))
clientCtx = try assertNoThrowWithValue(configuredSSLContextWithAlpnProtocols(protocols: ["spdy/3", "webrtc"]))
XCTAssertNoThrow(try assertNegotiatedProtocol(protocol: nil, serverContext: serverCtx, clientContext: clientCtx))
}
func testBasicALPNNegotiationNotOfferedByClient() throws {
let serverCtx: NIOSSLContext
let clientCtx: NIOSSLContext
serverCtx = try assertNoThrowWithValue(configuredSSLContextWithAlpnProtocols(protocols: ["h2", "http/1.1"]))
clientCtx = try assertNoThrowWithValue(configuredSSLContextWithAlpnProtocols(protocols: []))
XCTAssertNoThrow(try assertNegotiatedProtocol(protocol: nil, serverContext: serverCtx, clientContext: clientCtx))
}
func testBasicALPNNegotiationNotSupportedByServer() throws {
let serverCtx: NIOSSLContext
let clientCtx: NIOSSLContext
serverCtx = try assertNoThrowWithValue(configuredSSLContextWithAlpnProtocols(protocols: []))
clientCtx = try assertNoThrowWithValue(configuredSSLContextWithAlpnProtocols(protocols: ["h2", "http/1.1"]))
XCTAssertNoThrow(try assertNegotiatedProtocol(protocol: nil, serverContext: serverCtx, clientContext: clientCtx))
}
}
|