Wie soll Secure Transport TLS mit BSD-Sockets in Swift verwendet werden?

Ich versuche, @ zu verwendSicherer Transport mit BSD-Sockets mit Swift. Es scheint, als sollte es einfach genug sein, aber ich kann es nicht zum Laufen bringen und die Dokumentation zu diesem Thema ist knapp.

Ich habe mein Problem in einer einfachen "Socket" -Klasse zusammengefasst, in der ich (nach meinem besten Wissen) die Anforderungen des sicheren Transports erfüllt habe.

import Cocoa

class Socket: NSObject {

    private let hello = "Hello!"
    private var socketfd: Int32
    private var sock_addr: sockaddr

    private var sslContext: SSLContext?

    var sslWriteCallbackFunc: SSLWriteFunc {
        get {
            let ump = UnsafeMutablePointer<((SSLConnectionRef, UnsafePointer<Void>,
                UnsafeMutablePointer<Int>) -> OSStatus)>.alloc(1)

            ump.initialize(sslWriteCallback)

            return CFunctionPointer<((SSLConnectionRef, UnsafePointer<Void>,
                UnsafeMutablePointer<Int>) -> OSStatus)>(COpaquePointer(ump))
        }
    }

    var sslReadCallbackFunc: SSLReadFunc {
        get {
            let ump = UnsafeMutablePointer<((SSLConnectionRef, UnsafeMutablePointer<Void>,
                UnsafeMutablePointer<Int>) -> OSStatus)>.alloc(1)

            ump.initialize(sslReadCallback)

            return CFunctionPointer<((SSLConnectionRef, UnsafeMutablePointer<Void>,
                UnsafeMutablePointer<Int>) -> OSStatus)>(COpaquePointer(ump))
        }
    }

    init(address: String, port: UInt16) {
        socketfd = Darwin.socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)

        var addr = Darwin.sockaddr_in(sin_len: __uint8_t(sizeof(sockaddr_in)), sin_family: sa_family_t(AF_INET), sin_port: CFSwapInt16(port), sin_addr: in_addr(s_addr: inet_addr(address)), sin_zero: (0, 0, 0, 0, 0, 0, 0, 0))
        sock_addr = Darwin.sockaddr(sa_len: 0, sa_family: 0, sa_data: (0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0))
        Darwin.memcpy(&sock_addr, &addr, Int(sizeof(sockaddr_in)))

        super.init()
    }

    func connect() -> Socket {
        let err = Darwin.connect(socketfd, &sock_addr, socklen_t(sizeof(sockaddr_in)))

        return self
    }

    func makeSecure() -> Socket {
        if let umc = SSLCreateContext(nil, kSSLClientSide, kSSLStreamType) {
            sslContext = umc.takeRetainedValue()

            var status = SSLSetIOFuncs(sslContext!, sslReadCallbackFunc, sslWriteCallbackFunc)
            status = SSLSetConnection(sslContext!, &socketfd)

            SSLHandshake(sslContext!)
        }

        return self
    }

    func sendHello() -> Socket {
        let bytes = [UInt8](hello.utf8)
        let data = NSData(bytes: bytes, length: bytes.count)

        let test = UnsafeMutablePointer<Int>.alloc(1)
        test.initialize(bytes.count)

        self.sslWriteCallback(&socketfd, data: data.bytes, dataLength: test)

        return self
    }

    // MARK: - SSL Callback Methods

    func sslReadCallback(connection: SSLConnectionRef,
        data: UnsafeMutablePointer<Void>,
        dataLength: UnsafeMutablePointer<Int>) -> OSStatus {

            let bytesRead = read(socketfd, data, UnsafePointer<Int>(dataLength).memory)

            return noErr
    }

    func sslWriteCallback(connection: SSLConnectionRef,
        data: UnsafePointer<Void>,
        dataLength: UnsafeMutablePointer<Int>) -> OSStatus {

            let sent = Darwin.sendto(socketfd, data, UnsafePointer<Int>(dataLength).memory, 0, &sock_addr, socklen_t(sizeof(sockaddr_in)))
            if (sent < 0) {
                let error = NSError(domain: NSPOSIXErrorDomain, code: Int(errno), userInfo: nil)
                println(error.localizedDescription)
            } else {
                println("Sent \(sent) bytes (\(hello))")
            }

            return noErr
    }
}

Ich habe die Nicht-TLS-Socket-Kommunikation getestet, indem ich eine einfache Instanz erstellt habe:

let socket = Socket(address: "some-ip-address", port: 8080)
socket.connect().sendHello()

und Ausführen eines Echoservers auf dem Zielcomputer mithilfe von netcat. Das funktioniert gut.

nc -l -p 8080

Versuchen, den Socket in das TLS von Secure Transport (Aufruf der Methode makeSecure ()) einzubinden, führt beim Aufruf von SSLHandshake (...) zu einem Absturz mit dem Fehler EXC_BAD_ADDRESS (Code = 2, Adresse = ...). Hat jemand irgendwelche Hinweise darauf, was ich hier vermisse?

BEARBEITE

Ich kann sehen, Konsole löscht:

04/06/15 09:20:48,000 kernel[0]: Data/Stack execution not permitted: TheProject[pid 29184] at virtual address 0x100602000, protections were read-write

EDIT 2

Ich habe es mit Swift 2 in der Xcode 7 Beta zum Laufen gebracht. Siehe unten

Antworten auf die Frage(6)

Ihre Antwort auf die Frage