Returns true if decryption succeeded (even for empty content)
| 1002 | |
| 1003 | // Returns true if decryption succeeded (even for empty content) |
| 1004 | static bool ssl_decrypt(pn_transport_t *transport) |
| 1005 | { |
| 1006 | pni_ssl_t *ssl = transport->ssl; |
| 1007 | // Get SChannel to decrypt input. May have an incomplete Record, |
| 1008 | // exactly one, or more than one. Check also for session ending, |
| 1009 | // session renegotiation. |
| 1010 | |
| 1011 | SecBuffer recv_buffs[4]; |
| 1012 | recv_buffs[0].cbBuffer = ssl->sc_in_count; |
| 1013 | recv_buffs[0].BufferType = SECBUFFER_DATA; |
| 1014 | recv_buffs[0].pvBuffer = ssl->sc_inbuf; |
| 1015 | recv_buffs[1].BufferType = SECBUFFER_EMPTY; |
| 1016 | recv_buffs[2].BufferType = SECBUFFER_EMPTY; |
| 1017 | recv_buffs[3].BufferType = SECBUFFER_EMPTY; |
| 1018 | SecBufferDesc buff_desc; |
| 1019 | buff_desc.ulVersion = SECBUFFER_VERSION; |
| 1020 | buff_desc.cBuffers = 4; |
| 1021 | buff_desc.pBuffers = recv_buffs; |
| 1022 | SECURITY_STATUS status = DecryptMessage(&ssl->ctxt_handle, &buff_desc, 0, NULL); |
| 1023 | |
| 1024 | if (status == SEC_E_INCOMPLETE_MESSAGE) { |
| 1025 | // Less than a full Record, come back later with more network data |
| 1026 | ssl->sc_in_incomplete = true; |
| 1027 | return false; |
| 1028 | } |
| 1029 | |
| 1030 | ssl->decrypting = false; |
| 1031 | |
| 1032 | if (status != SEC_E_OK) { |
| 1033 | rewind_sc_inbuf(ssl); |
| 1034 | switch (status) { |
| 1035 | case SEC_I_CONTEXT_EXPIRED: |
| 1036 | // TLS shutdown alert record. Ignore all subsequent input. |
| 1037 | ssl->state = SHUTTING_DOWN; |
| 1038 | ssl->sc_input_shutdown = true; |
| 1039 | return false; |
| 1040 | |
| 1041 | case SEC_I_RENEGOTIATE: |
| 1042 | ssl_log_error("unexpected TLS renegotiation"); |
| 1043 | // TODO. Fall through for now. |
| 1044 | default: |
| 1045 | ssl_failed(transport, 0); |
| 1046 | return false; |
| 1047 | } |
| 1048 | } |
| 1049 | |
| 1050 | ssl->decrypting = false; |
| 1051 | // have a decrypted Record and possible (still-encrypted) data of |
| 1052 | // one (or more) later Recordss. Adjust pointers accordingly. |
| 1053 | for (int i = 0; i < 4; i++) { |
| 1054 | switch (recv_buffs[i].BufferType) { |
| 1055 | case SECBUFFER_DATA: |
| 1056 | ssl->in_data = (char *) recv_buffs[i].pvBuffer; |
| 1057 | ssl->in_data_size = ssl->in_data_count = recv_buffs[i].cbBuffer; |
| 1058 | break; |
| 1059 | case SECBUFFER_EXTRA: |
| 1060 | ssl->inbuf_extra = (char *)recv_buffs[i].pvBuffer; |
| 1061 | ssl->extra_count = recv_buffs[i].cbBuffer; |
no test coverage detected