Open majumd opened 4 years ago
Hi @majumd , TLS version enforcement shouldn't be done from client side. Client side provides a maximum version it supports, and server side picks one. So Client cannot enforce a high version while reject a lower version. (Update on 3/21/2022: TLS version enforcement can be done and should be done from client-side, to avoid MITM TLS downgrade attack)
It can be done in configuration of a storage account on Azure Portal.
For other features you've mentioned, they are all platform specific. As a client library we want to be portable, so we cannot do it in our library. But we do expose an API with which you can get the connection handle every time a new connection is established. Check it here. You can specify a callback function, and do those platform specific stuff in that callback function.
Thanks for the response. What would be the way to initialize m_ssl_context_callback and m_native_session_handle_options_callback of class _operation_context so that they would apply for any connections made using the client library?
Do we need to define a static function in class operation_context similar to set_default_log_level() to set the callback at global scope? or is there any other method to define the callback function in a global scope?
@majumd Every function that's going to make a network connection has at least one overload that will accept an operation context in parameter. For example, for blob container create function, we have a overload here. It accepts an operation_context
.
So what you need to do is
void(web::http::client::native_handle)
operation_context::set_native_session_handle_options_callback
with the callback function you just defined in 1.In this way, every time a connection is established, the callback will get called and in that callback function you can do something you want to the connection handle.
The below sample program validates whether the container exists given connection string. The sample program would use default operation_context object which would not have the custom callback functions set. azure::storage::cloud_storage_account storage_account = azure::storage::cloud_storage_account::parse(storage_connection_string); azure::storage::cloud_blob_client blob_client = storage_account.create_cloud_blob_client(); azure::storage::cloud_blob_container container = blob_client.get_container_reference(_XPLATSTR("my-sample-container")); container.exists();
To make the plugin go through custom callback handler, the below function needs to be called. exists_async(const blob_request_options& options, operation_context context) function.
This leaves a chance of programming error where a developer might call a function without an operation_context and it might not abide by the security considerations a client program should have enforced.
It would be nice to enforce the security considerations on whatever function call is made by the developer. An ability where the client program could set the default callback function at the start of the program and all service function calls uses the same operation context defaults would have been nice.
To make the plugin go through custom callback handler, the below function needs to be called. exists_async(const blob_request_options& options, operation_context context) function.
If you want sync version API, you can also call exists(const blob_request_options& options, operation_context context)
This leaves a chance of programming error where a developer might call a function without an operation_context and it might not abide by the security considerations a client program should have enforced.
It would be nice to enforce the security considerations on whatever function call is made by the developer. An ability where the client program could set the default callback function at the start of the program and all service function calls uses the same operation context defaults would have been nice.
I think what you need here is a method to change the global configuration. As far as I know, storage sdk doesn't provide this functionality. Since storage sdk uses cpprestsdk as HTTP client, maybe there's something you can do with cpprest. Anyway, that's already out of the scope of this sdk, maybe you want to create an issue in https://github.com/microsoft/cpprestsdk?
I do not understand how this all works but when I set my server side on TLS 1.2 my client refuses to connect. is there something wrong with the pc settings or do I need to add a line in my client code to say it uses TLS 1.2?
@hielkedehaan Does it work if you set a lower TLS version on your server side? If it does, maybe it's because underlying HTTP client doesn't support TLS 1.2. Can you share the environment your application is running in?
Yes a lower TLS version works only I do not seem to be able to get the client communicating when I set it to 1.2. Thank you for the quick response.
This is an old issue, but just in case anybody else will be directed here by search engine, this is how to enfore TLS1.2 on Windows:
azure::storage::operation_context context;
context.set_native_session_handle_options_callback([](web::http::client::native_handle h) {
auto tlsOption = WINHTTP_FLAG_SECURE_PROTOCOL_TLS1_2;
WinHttpSetOption(
h,
WINHTTP_OPTION_SECURE_PROTOCOLS,
&tlsOption,
sizeof(tlsOption));
});
b.download_text(azure::storage::access_condition(), azure::storage::blob_request_options(), context);
You need to include winhttp.h
and link to winhttp.lib
to use this function.
Hi, The client library could specify to use the https endpoint to connect to Azure. However it uses the OS certificate store for the root certificates. We would like to use the client library and would like to have few enhancements in view of security. 1) We would like to have ability to specify a custom certificate store instead of using the default OS certificate store. 2) We would like to disable use of SSLv2, SSLv3, TLS1.0 TLS 1.1 and only enforce TLS 1.2 3) We would like to enforce a list of hardened TLS cipher suites. 4) We would like to have ability to specify the revocation list so that revoked certificates are not used for SSL connections.
Could you please tell whether these feature requests could be done?