| 1250 | |
| 1251 | |
| 1252 | static void server_handshake(pn_transport_t* transport) |
| 1253 | { |
| 1254 | pni_ssl_t *ssl = transport->ssl; |
| 1255 | if (!ssl->protocol_detected) { |
| 1256 | // SChannel fails less aggressively than openssl on client hello, causing hangs |
| 1257 | // waiting for more bytes. Help out here. |
| 1258 | pni_protocol_type_t type = pni_sniff_header(ssl->sc_inbuf, ssl->sc_in_count); |
| 1259 | if (type == PNI_PROTOCOL_INSUFFICIENT) { |
| 1260 | ssl_log(transport, PN_LEVEL_DEBUG, "server handshake: incomplete record"); |
| 1261 | ssl->sc_in_incomplete = true; |
| 1262 | return; |
| 1263 | } else { |
| 1264 | ssl->protocol_detected = true; |
| 1265 | if (type != PNI_PROTOCOL_SSL) { |
| 1266 | ssl_failed(transport, "bad client hello"); |
| 1267 | ssl->decrypting = false; |
| 1268 | rewind_sc_inbuf(ssl); |
| 1269 | return; |
| 1270 | } |
| 1271 | } |
| 1272 | } |
| 1273 | |
| 1274 | // Feed SChannel ongoing handshake records from the client until the handshake is complete. |
| 1275 | ULONG ctxt_requested = ASC_REQ_STREAM | ASC_REQ_EXTENDED_ERROR; |
| 1276 | if (ssl->verify_mode == PN_SSL_VERIFY_PEER || ssl->verify_mode == PN_SSL_VERIFY_PEER_NAME) |
| 1277 | ctxt_requested |= ASC_REQ_MUTUAL_AUTH; |
| 1278 | ULONG ctxt_attrs; |
| 1279 | size_t max = 0; |
| 1280 | |
| 1281 | // token_buffs describe the buffer that's coming in. It should have |
| 1282 | // a token from the SSL client except if shutting down or renegotiating. |
| 1283 | bool shutdown = ssl->state == SHUTTING_DOWN; |
| 1284 | SecBuffer token_buffs[2]; |
| 1285 | token_buffs[0].cbBuffer = shutdown ? 0 : ssl->sc_in_count; |
| 1286 | token_buffs[0].BufferType = SECBUFFER_TOKEN; |
| 1287 | token_buffs[0].pvBuffer = shutdown ? 0 : ssl->sc_inbuf; |
| 1288 | token_buffs[1].cbBuffer = 0; |
| 1289 | token_buffs[1].BufferType = SECBUFFER_EMPTY; |
| 1290 | token_buffs[1].pvBuffer = 0; |
| 1291 | SecBufferDesc token_buff_desc; |
| 1292 | token_buff_desc.ulVersion = SECBUFFER_VERSION; |
| 1293 | token_buff_desc.cBuffers = 2; |
| 1294 | token_buff_desc.pBuffers = token_buffs; |
| 1295 | |
| 1296 | // send_buffs will hold information to forward to the peer. |
| 1297 | SecBuffer send_buffs[2]; |
| 1298 | send_buffs[0].cbBuffer = ssl->sc_out_size; |
| 1299 | send_buffs[0].BufferType = SECBUFFER_TOKEN; |
| 1300 | send_buffs[0].pvBuffer = ssl->sc_outbuf; |
| 1301 | send_buffs[1].cbBuffer = 0; |
| 1302 | send_buffs[1].BufferType = SECBUFFER_EMPTY; |
| 1303 | send_buffs[1].pvBuffer = 0; |
| 1304 | SecBufferDesc send_buff_desc; |
| 1305 | send_buff_desc.ulVersion = SECBUFFER_VERSION; |
| 1306 | send_buff_desc.cBuffers = 2; |
| 1307 | send_buff_desc.pBuffers = send_buffs; |
| 1308 | PCtxtHandle ctxt_handle_ptr = (SecIsValidHandle(&ssl->ctxt_handle)) ? &ssl->ctxt_handle : 0; |
| 1309 |
no test coverage detected