Discussion:
error in winhttpqueryoption for retriving server's digital certificate......
(too old to reply)
selva
2006-11-27 07:23:26 UTC
Permalink
hi,
i need to retrive the digital certificate stored at the server from
the client,hence i used winhttpQueryOption functions as follows


public struct WINHTTP_CERTIFICATE_INFO {
string ftExpiry;
string ftStart;
string lpszSubjectInfo;
string lpszIssuerInfo;
string lpszProtocolName;
string lpszSignatureAlgName;
string lpszEncryptionAlgName;
int dwKeySize;
};


WINHTTP_CERTIFICATE_INFO certificate= new
Win32Api.WINHTTP_CERTIFICATE_INFO();

WinHttpQueryOption(id,WINHTTP_OPTION_SERVER_CERT_CONTEXT , ref
certificate,sizeof(certificate));


where id is my connection handle...


but it's returning invalid parameters error.

please help me regarding this issue for retriving the certificate from
server.

regards
bharathi
Stephen Sulzer
2006-11-27 08:12:25 UTC
Permalink
bharathi,

You need to send a request to the server before you can query for the
server's certificate information. Then use the request handle in the call to
WinHttpQueryOption. The SERVER_CERT_CONTEXT option can only be queried on a
request handle. WinHttp does not actually establish any connection with a
server until the call to WinHttpSendRequest. You should be able to query the
server's certificate right after WinHttpSendRequest and before any calls to
WinHttpWriteData/WinHttpReceiveResponse.

Regards,
- Stephen
selva
2006-11-27 08:41:38 UTC
Permalink
thanks stephen for ur valuble reply
actually my entire code is as follows

using System;
using WinHttp;
namespace PacProxyUsage
{

public class Proxy
{
public Proxy()
{
}


unsafe public static string GetProxyForUrlUsingPac ( string
DestinationUrl, string PacUri ){
WinHttpRequest req=new WinHttpRequest();
IntPtr WinHttpSession = Win32Api.WinHttpOpen("User",
Win32Api.WINHTTP_ACCESS_TYPE_DEFAULT_PROXY, null, IntPtr.Zero, 0);

char [] buf=new char[100];

Win32Api.WINHTTP_AUTOPROXY_OPTIONS ProxyOptions = new
Win32Api.WINHTTP_AUTOPROXY_OPTIONS();
Win32Api.WINHTTP_PROXY_INFO ProxyInfo = new
Win32Api.WINHTTP_PROXY_INFO();
Win32Api.WINHTTP_CERTIFICATE_INFO certificate= new
Win32Api.WINHTTP_CERTIFICATE_INFO();
ProxyOptions.dwFlags =
Win32Api.WINHTTP_AUTOPROXY_CONFIG_URL;
ProxyOptions.dwAutoDetectFlags =
(Win32Api.WINHTTP_AUTO_DETECT_TYPE_DHCP |
Win32Api.WINHTTP_AUTO_DETECT_TYPE_DNS_A);
ProxyOptions.lpszAutoConfigUrl = PacUri;


bool IsSuccess = Win32Api.WinHttpGetProxyForUrl(
WinHttpSession, DestinationUrl, ref ProxyOptions, ref ProxyInfo );
string url;
bool
flag=Win32Api.WinHttpDetectAutoProxyConfigUrl(Win32Api.WINHTTP_AUTO_DETECT_TYPE_DHCP,out
url);
Console.WriteLine(url);
IntPtr WinHttpSession1 = Win32Api.WinHttpOpen("User",
Win32Api.WINHTTP_ACCESS_TYPE_NAMED_PROXY, ProxyInfo.lpszProxy,
IntPtr.Zero, 0);
IntPtr
Winconnection=Win32Api.WinHttpConnect(WinHttpSession,"www.mygdc.com",0,0);
IntPtr
id=Win32Api.WinHttpOpenRequest(Winconnection,"POST","/winn/01Primary/",null,null,null,0x00800000);
int dwword = Win32Api.SECURITY_FLAG_IGNORE_CERT_CN_INVALID |

Win32Api.SECURITY_FLAG_IGNORE_CERT_DATE_INVALID |
Win32Api.SECURITY_FLAG_IGNORE_UNKNOWN_CA;

int
size=System.Runtime.InteropServices.Marshal.SizeOf(dwword);

Win32Api.WinHttpSetOption(id,31, &dwword,size);

Console.WriteLine("Error: {0}", Win32Api.GetLastError() );

bool result1=Win32Api.WinHttpSendRequest(id,null,0,null,0,0,0);

bool res=
Win32Api.WinHttpSetCredentials(id,Win32Api.WINHTTP_AUTH_TARGET_SERVER,Win32Api.WINHTTP_AUTH_SCHEME_BASIC,"test","test",null);

bool re=Win32Api.WinHttpReceiveResponse(id,null);

WinHttpQueryOption(id,WINHTTP_OPTION_SERVER_CERT_CONTEXT , ref
certificate,sizeof(certificate));




Console.WriteLine("Error: {0}", Win32Api.GetLastError() );
Win32Api.WinHttpCloseHandle(WinHttpSession1);
Win32Api.WinHttpCloseHandle(Winconnection);
if (IsSuccess){
return ProxyInfo.lpszProxy;
}else {
Console.WriteLine("Error: {0}", Win32Api.GetLastError()
);
return null;
}
}

}
}



but my winhttpqueryoption function returning invalid parameters.
please help me to solve this problem for retriving the server's
certificate.

regards
bharathi
Post by Stephen Sulzer
bharathi,
You need to send a request to the server before you can query for the
server's certificate information. Then use the request handle in the call to
WinHttpQueryOption. The SERVER_CERT_CONTEXT option can only be queried on a
request handle. WinHttp does not actually establish any connection with a
server until the call to WinHttpSendRequest. You should be able to query the
server's certificate right after WinHttpSendRequest and before any calls to
WinHttpWriteData/WinHttpReceiveResponse.
Regards,
- Stephen
Stephen Sulzer
2006-12-01 19:45:31 UTC
Permalink
It seems that after calling WinHttpQueryOption your code is always calling
GetLastError. But you should only call GetLastError if the API returns
false. You need to first check the Boolean value returned from
WinHttpQueryOption: if it returns true it means it succeeded and there is no
need to call GetLastError (since there is no error). GetLastError returns
the error code of the last API which failed. (If an API succeeds, it may not
reset GetLastError to 0.)

- Stephen
selva
2006-12-04 04:30:26 UTC
Permalink
thanks stephen
my winttpqueryoption is returning false and the error 87 parameter
incorrect,please tell me the correct marshelling of parameters inside
the winhttpqueryoption()function

please help me regarding this issue...

regards
bharathi
Post by Stephen Sulzer
It seems that after calling WinHttpQueryOption your code is always calling
GetLastError. But you should only call GetLastError if the API returns
false. You need to first check the Boolean value returned from
WinHttpQueryOption: if it returns true it means it succeeded and there is no
need to call GetLastError (since there is no error). GetLastError returns
the error code of the last API which failed. (If an API succeeds, it may not
reset GetLastError to 0.)
- Stephen
Stephen Sulzer
2006-12-09 09:38:30 UTC
Permalink
The last parameter of WinHttpQueryOption, the size of the buffer, must be
passed by reference. From the MSDN documentation:

lpdwBufferLength
[in, out] Pointer to an unsigned long integer variable that contains the
length of lpBuffer, in bytes. When the function returns, the variable
receives the length of the data placed into lpBuffer. If GetLastError
returns ERROR_INSUFFICIENT_BUFFER, this parameter receives the number of
bytes required to hold the requested information.

http://msdn2.microsoft.com/en-us/library/aa384103.aspx


- Stephen

Loading...