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; }
p12_error p12decode(pkcs12_context * context, CFDataRef cdpfx) { int err = p12_decodeErr; NSS_P12_DecodedPFX pfx; memset(&pfx, 0, sizeof(pfx)); SecAsn1Item raw_blob = { CFDataGetLength(cdpfx), (void*)CFDataGetBytePtr(cdpfx) }; require_noerr_quiet(decode_item(context, &raw_blob, NSS_P12_DecodedPFXTemplate, &pfx), out); NSS_P7_DecodedContentInfo *dci = &pfx.authSafe; /* only support CT_Data at top level (password based integrity mode) */ require(dci->type == CT_Data, out); require(pfx.macData, out); require_noerr_action_quiet(p12VerifyMac(context, &pfx), out, err = p12_passwordErr); require_noerr_quiet(authSafeParse(context, dci->content.data), out); return errSecSuccess; out: return err; }
static OSStatus securetransport(ssl_test_handle * ssl) { OSStatus ortn; SSLContextRef ctx = ssl->st; SecTrustRef trust = NULL; bool got_server_auth = false, got_client_cert_req = false; ortn = SSLHandshake(ctx); //fprintf(stderr, "Fell out of SSLHandshake with error: %ld\n", (long)ortn); size_t sent, received; const char *r=request; size_t l=sizeof(request); do { ortn = SSLWrite(ctx, r, l, &sent); if(ortn == errSSLWouldBlock) { r+=sent; l-=sent; } if (ortn == errSSLServerAuthCompleted) { require_string(!got_server_auth, out, "second server auth"); require_string(!got_client_cert_req, out, "got client cert req before server auth"); got_server_auth = true; require_string(!trust, out, "Got errSSLServerAuthCompleted twice?"); /* verify peer cert chain */ require_noerr(SSLCopyPeerTrust(ctx, &trust), out); SecTrustResultType trust_result = 0; /* this won't verify without setting up a trusted anchor */ require_noerr(SecTrustEvaluate(trust, &trust_result), out); } } while(ortn == errSSLWouldBlock || ortn == errSSLServerAuthCompleted); //fprintf(stderr, "\nHTTP Request Sent\n"); require_noerr_action_quiet(ortn, out, printf("SSLWrite failed with err %ld\n", (long)ortn)); require_string(got_server_auth, out, "never got server auth"); do { ortn = SSLRead(ctx, reply, sizeof(reply)-1, &received); //fprintf(stderr, "r"); usleep(1000); } while(ortn == errSSLWouldBlock); //fprintf(stderr, "\n"); require_noerr_action_quiet(ortn, out, printf("SSLRead failed with err %ld\n", (long)ortn)); reply[received]=0; //fprintf(stderr, "HTTP reply:\n"); //fprintf(stderr, "%s\n",reply); out: SSLClose(ctx); SSLDisposeContext(ctx); if (trust) CFRelease(trust); return ortn; }