static void *securetransport_ssl_thread(void *arg) { OSStatus ortn; int sock = (int)arg; int socket = accept(sock, NULL, NULL); CFArrayRef server_certs = server_chain(); ssl_test_handle * ssl = ssl_test_handle_create(socket, server_certs); SSLContextRef ctx = ssl->st; pthread_setname_np("server thread"); //uint64_t start = mach_absolute_time(); do { ortn = SSLHandshake(ctx); } while (ortn == errSSLWouldBlock); require_noerr_action_quiet(ortn, out, fprintf(stderr, "Fell out of SSLHandshake with error: %d\n", (int)ortn)); //uint64_t elapsed = mach_absolute_time() - start; //fprintf(stderr, "setr elapsed: %lld\n", elapsed); /* SSLProtocol proto = kSSLProtocolUnknown; require_noerr_quiet(SSLGetNegotiatedProtocolVersion(ctx, &proto), out); */ SSLCipherSuite cipherSuite; require_noerr_quiet(ortn = SSLGetNegotiatedCipher(ctx, &cipherSuite), out); //fprintf(stderr, "st negotiated %s\n", sslcipher_itoa(cipherSuite)); out: CFRelease(server_certs); SSLClose(ctx); CFRelease(ctx); if(ssl) { close(ssl->comm); free(ssl); } pthread_exit((void *)(intptr_t)ortn); return NULL; }
int dtls_client(const char *hostname, int bypass) { int fd; int tlsfd; struct sockaddr_in sa; printf("Running dtls_client test with hostname=%s, bypass=%d\n", hostname, bypass); if ((fd=socket(AF_INET, SOCK_DGRAM, 0))==-1) { perror("socket"); exit(-1); } memset((char *) &sa, 0, sizeof(sa)); sa.sin_family = AF_INET; sa.sin_port = htons(PORT); if (inet_aton(hostname, &sa.sin_addr)==0) { fprintf(stderr, "inet_aton() failed\n"); exit(1); } if(connect(fd, (struct sockaddr *)&sa, sizeof(sa))==-1) { perror("connect"); return errno; } /* Change to non blocking io */ fcntl(fd, F_SETFL, O_NONBLOCK); SSLRecordContextRef c=(intptr_t)fd; OSStatus ortn; SSLContextRef ctx = NULL; SSLClientCertificateState certState; SSLCipherSuite negCipher; SSLProtocol negVersion; /* * Set up a SecureTransport session. */ ctx = SSLCreateContextWithRecordFuncs(kCFAllocatorDefault, kSSLClientSide, kSSLDatagramType, &TLSSocket_Funcs); if(!ctx) { printSslErrStr("SSLCreateContextWithRecordFuncs", -1); return -1; } printf("Attaching filter\n"); ortn = TLSSocket_Attach(fd); if(ortn) { printSslErrStr("TLSSocket_Attach", ortn); return ortn; } if(bypass) { tlsfd = open("/dev/tlsnke", O_RDWR); if(tlsfd<0) { perror("opening tlsnke dev"); exit(-1); } } ortn = SSLSetRecordContext(ctx, c); if(ortn) { printSslErrStr("SSLSetRecordContext", ortn); return ortn; } ortn = SSLSetMaxDatagramRecordSize(ctx, 600); if(ortn) { printSslErrStr("SSLSetMaxDatagramRecordSize", ortn); return ortn; } /* Lets not verify the cert, which is a random test cert */ ortn = SSLSetEnableCertVerify(ctx, false); if(ortn) { printSslErrStr("SSLSetEnableCertVerify", ortn); return ortn; } ortn = SSLSetCertificate(ctx, server_chain()); if(ortn) { printSslErrStr("SSLSetCertificate", ortn); return ortn; } printf("Handshake...\n"); do { ortn = SSLHandshake(ctx); if(ortn == errSSLWouldBlock) { /* keep UI responsive */ sslOutputDot(); } } while (ortn == errSSLWouldBlock); SSLGetClientCertificateState(ctx, &certState); SSLGetNegotiatedCipher(ctx, &negCipher); SSLGetNegotiatedProtocolVersion(ctx, &negVersion); int count; size_t len; ssize_t sreadLen, swriteLen; size_t readLen, writeLen; char buffer[BUFLEN]; count = 0; while(count<COUNT) { int timeout = 10000; snprintf(buffer, BUFLEN, "Message %d", count); len = strlen(buffer); if(bypass) { /* Send data through the side channel, kind of like utun would */ swriteLen=write(tlsfd, buffer, len); if(swriteLen<0) { perror("write to tlsfd"); break; } writeLen=swriteLen; } else { ortn=SSLWrite(ctx, buffer, len, &writeLen); if(ortn) { printSslErrStr("SSLWrite", ortn); break; } } printf("Wrote %lu bytes\n", writeLen); count++; if(bypass) { do { sreadLen=read(tlsfd, buffer, BUFLEN); } while((sreadLen==-1) && (errno==EAGAIN) && (timeout--)); if((sreadLen==-1) && (errno==EAGAIN)) { printf("Read timeout...\n"); continue; } if(sreadLen<0) { perror("read from tlsfd"); break; } readLen=sreadLen; } else { do { ortn=SSLRead(ctx, buffer, BUFLEN, &readLen); } while((ortn==errSSLWouldBlock) && (timeout--)); if(ortn==errSSLWouldBlock) { printf("SSLRead timeout...\n"); continue; } if(ortn) { printSslErrStr("SSLRead", ortn); break; } } buffer[readLen]=0; printf("Received %lu bytes: %s\n", readLen, buffer); } SSLClose(ctx); SSLDisposeContext(ctx); return ortn; }