PROTON-887: SChannel version of pn_ssl_get_remote_subject()
Project: http://git-wip-us.apache.org/repos/asf/qpid-proton/repo Commit: http://git-wip-us.apache.org/repos/asf/qpid-proton/commit/2117b3b6 Tree: http://git-wip-us.apache.org/repos/asf/qpid-proton/tree/2117b3b6 Diff: http://git-wip-us.apache.org/repos/asf/qpid-proton/diff/2117b3b6 Branch: refs/heads/kgiusti-python3 Commit: 2117b3b6d9ebd1e6a157c437017f0456dc13a2f3 Parents: c2c178c Author: Clifford Jansen <cliffjan...@apache.org> Authored: Tue Jun 16 07:42:42 2015 -0700 Committer: Clifford Jansen <cliffjan...@apache.org> Committed: Tue Jun 16 07:42:42 2015 -0700 ---------------------------------------------------------------------- proton-c/src/windows/schannel.c | 53 ++++++++++++++++++++++++++++-------- 1 file changed, 42 insertions(+), 11 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/2117b3b6/proton-c/src/windows/schannel.c ---------------------------------------------------------------------- diff --git a/proton-c/src/windows/schannel.c b/proton-c/src/windows/schannel.c index 757a108..28550fb 100644 --- a/proton-c/src/windows/schannel.c +++ b/proton-c/src/windows/schannel.c @@ -283,6 +283,7 @@ struct pni_ssl_t { SecPkgContext_StreamSizes sc_sizes; pn_ssl_verify_mode_t verify_mode; win_credential_t *cred; + char *subject; }; static inline pn_transport_t *get_transport_internal(pn_ssl_t *ssl) @@ -728,6 +729,7 @@ void pn_ssl_free( pn_transport_t *transport) if (ssl->sc_inbuf) free((void *)ssl->sc_inbuf); if (ssl->sc_outbuf) free((void *)ssl->sc_outbuf); if (ssl->inbuf2) pn_buffer_free(ssl->inbuf2); + if (ssl->subject) free(ssl->subject); free(ssl); } @@ -811,10 +813,39 @@ int pn_ssl_get_peer_hostname( pn_ssl_t *ssl0, char *hostname, size_t *bufsize ) return 0; } -const char* pn_ssl_get_remote_subject(pn_ssl_t *ssl) +const char* pn_ssl_get_remote_subject(pn_ssl_t *ssl0) { - //TODO: actual implementation - return NULL; + // RFC 2253 compliant, but differs from openssl's subject string with space separators and + // ordering of multicomponent RDNs. Made to work as similarly as possible with choice of flags. + pni_ssl_t *ssl = get_ssl_internal(ssl0); + if (!ssl || !SecIsValidHandle(&ssl->ctxt_handle)) + return NULL; + if (!ssl->subject) { + SECURITY_STATUS status; + PCCERT_CONTEXT peer_cc = 0; + status = QueryContextAttributes(&ssl->ctxt_handle, SECPKG_ATTR_REMOTE_CERT_CONTEXT, &peer_cc); + if (status != SEC_E_OK) { + ssl_log_error_status(status, "can't obtain remote certificate subject"); + return NULL; + } + DWORD flags = CERT_X500_NAME_STR | CERT_NAME_STR_REVERSE_FLAG; + DWORD strlen = CertNameToStr(peer_cc->dwCertEncodingType, &peer_cc->pCertInfo->Subject, + flags, NULL, 0); + if (strlen > 0) { + ssl->subject = (char*) malloc(strlen); + if (ssl->subject) { + DWORD len = CertNameToStr(peer_cc->dwCertEncodingType, &peer_cc->pCertInfo->Subject, + flags, ssl->subject, strlen); + if (len != strlen) { + free(ssl->subject); + ssl->subject = NULL; + ssl_log_error("pn_ssl_get_remote_subject failure in CertNameToStr"); + } + } + } + CertFreeCertificateContext(peer_cc); + } + return ssl->subject; } @@ -1678,16 +1709,16 @@ static ssize_t process_output_ssl( pn_transport_t *transport, unsigned int layer if (ssl->network_out_pending == 0) { if (ssl->state == SHUTTING_DOWN) { - if (!ssl->queued_shutdown) { - start_ssl_shutdown(transport); - work_pending = true; - } else { - ssl->state = SSL_CLOSED; - } + if (!ssl->queued_shutdown) { + start_ssl_shutdown(transport); + work_pending = true; + } else { + ssl->state = SSL_CLOSED; + } } else if (ssl->state == NEGOTIATING && ssl->app_input_closed) { - ssl->app_output_closed = PN_EOS; - ssl->state = SSL_CLOSED; + ssl->app_output_closed = PN_EOS; + ssl->state = SSL_CLOSED; } } } while (work_pending); --------------------------------------------------------------------- To unsubscribe, e-mail: commits-unsubscr...@qpid.apache.org For additional commands, e-mail: commits-h...@qpid.apache.org