News  [SoftwareSite

Latest News
Older News
RSS Feed
 
Complete Projects
Useful Classes
Top Downloads
Message Board
AllAPI.net
 
Send Comments
Software License
Mentalis.org Buttons
Donate
 
Forums -> Security Tools for .NET 2.0 Forum
 
64bit error

Reply

by steve james [s at james dot com]
posted on 2008/01/14

Hi,
Thanks for the great libs. I have a question I'm hoping you could help me with. I used your original sec lib, and it's integrated into our stuff quite heavily, so it's not easy to just rip out and replace. I'm hoping you can point me in the right direction.

The original code has this:

[DllImport(@"crypt32.dll")]
internal static extern int CertGetPublicKeyLength(int dwCertEncodingType, IntPtr pPublicKey);

Which, through a few methods, is called by:

int length=m_RemoteCertificate.GetPublicKeyLength();
if (length< 512) {
throw new SslException(AlertDescription.HandshakeFailure, "The public key should be at least 512 bits" );

in the "internal abstract class HandshakeLayer" code.

This code fails under .NET 2.0 running under 64 bit. CertGetPublicKeyLength(...) returns 0 for the length. The code works correctly under 32 bit machines, so it appears to be a bug in the 64bit 2003 OS.

Can you point me in the right direction on what to do? Due to a combination of servers I would like the same code to run on both 32 and 64 bit machines. However, beggers can't be choosers.

Any thing you can do to help to point me in the right direction will be greatly appreciated.

Thanks!

by Michael Hansen [michael at berantzino dot net]
posted on 2008/03/05
Reply

Hi!

I have the exact same problem - did you ever resolve this issue?


Best regards,

Michael

by Michael Hansen [michael at berantzino dot net]
posted on 2008/03/05
Reply

Hi again,

Shortly after writting my previous thread - I found this:
"Applications that use the Cryptography API cannot validate an X.509 certificate in Windows Server 2003" (http://support.microsoft.com/kb/938397)


Now, for me at least, I am working on a Win2k3 x64 machine - why this could be the cause of the problem.

/Michale

by Michael Hansen [michael at berantzino dot net]
posted on 2008/03/05
Reply

Hi again, again, and again,

I found the following KB article: http://support.microsoft.com/kb/938759/en-us

This contains a patch to Crypt32.dll released february 12 2008 - however, this did not solve the problem.

I therefore went back to trying to pinpoint the exact location of the error - and the error code thereof.

It turns out that it most certainly is the win32 call to "CertGetPublicKeyLength" in SspiProvider that is causing the problem. This sets an error code - which translates to:

"ASN1 bad tag value met"

However I have absolutely no clue to how fix this.

From MSDN I can see that it accepts a pointer to a CERT_PUBLIC_KEY_INFO - which in Mentalis translates to new IntPtr(m_Context.pCertInfo.ToInt64() + 56)


Could it be that this offset (+56) is wrong on x64?

I have tested it on both win2k3 and win2k8 - both x64 - and both fail - whereas win2k3 x86 works perfectly.


/Michael

by Van Glass [vglass at jscape dot com]
posted on 2008/12/04
Reply

Does anyone know if this has been fixed yet or if there are plans for it to be fixed?

by Pieter Philippaerts [Pieter at mentalis dot org]
posted on 2009/06/27
Reply

It seems that you are correct - the offset of 56 bytes is wrong on x64. Looking at the MSDN documentation, I believe it should be 76 bytes on x64 machines. Can you test and verify this?

by David [david at briosolutions dot net]
posted on 2009/09/21
Reply

Did anyone ever find a solution to this issue. I have tried the 76 bit offset and it still doesn\'t work for me.

by Thomas [Thomas dot Schneider01 at t-systems dot com]
posted on 2009/09/23
Reply

Hello;

I made a workaround for this problem. Therefore I add the following lines into the Security\\Certificates\\Certificate.sc file after \"m_Context = \":

//Thomas Schneider: Workaround 64Bit systems, 19th September 2009
if (Environment.GetEnvironmentVariable(\"ProgramFiles(x86)\") != null)
{
int _all = Marshal.SizeOf(m_Context); //40 !!!!! (should be 32), (20 on 32bit systems)
int _cont1 = Marshal.SizeOf(m_Context.cbCertEncoded); // 4
int _cont2 = Marshal.SizeOf(m_Context.dwCertEncodingType); // 4
int _cont3 = Marshal.SizeOf(m_Context.hCertStore); // 8 (4 on 32bit systems)
int _cont4 = Marshal.SizeOf(m_Context.pbCertEncoded); // 8 (4 on 32bit systems)
int _cont5 = Marshal.SizeOf(m_Context.pCertInfo); // 8 (4 on 32bit systems)
int _memleak = _all - _cont1 - _cont2 - _cont3 - _cont4 - _cont5; // 8 (should be 0), (0 on 32bit systems)

if (_memleak != 0)
m_Context.pCertInfo = new IntPtr(m_Context.pCertInfo.ToInt64() + _memleak);
}

The problem is that the structure \"CertificateContext\" has a wrong length and that the embedded structure \"CertificateInfo\" is shifted 8Bytes, so that all query results to \"CertificateInfo\" delivers a wrong answer. My workaround works fine in my test environment, but I couldn\'t get the answer, why this happened. Has anyone an idea?

To avoid pointer problems in the method \"GetPublicKeyLength\" it is higly recommended not to use it. Instead you could use \"<Certificate>.PublicKey.KeySize\" on all parts it is used.

I hope this will help you and I\'m looking forward to find someone who resolves the problem, so that the workaround is not necessary.

If possible there should be created a new version in the download area.

by Jitbit [jitbit at gmail dot com]
posted on 2010/11/17
Reply

The fix does not work, it throws an exception: \"AccessViolationException: Attempted to read or write protected memory. This is often an indication that other memory is corrupt\"

by Jitbit [jitbit at gmail dot com]
posted on 2010/11/17
Reply

Oh, I think managed to make it work. You just have to add \"unsafe\" to the pointer assignment:

if (Environment.GetEnvironmentVariable(\"ProgramFiles(x86)\") != null)
{
int _all = Marshal.SizeOf(m_Context); //40 !!!!! (should be 32), (20 on 32bit systems)
int _cont1 = Marshal.SizeOf(m_Context.cbCertEncoded); // 4
int _cont2 = Marshal.SizeOf(m_Context.dwCertEncodingType); // 4
int _cont3 = Marshal.SizeOf(m_Context.hCertStore); // 8 (4 on 32bit systems)
int _cont4 = Marshal.SizeOf(m_Context.pbCertEncoded); // 8 (4 on 32bit systems)
int _cont5 = Marshal.SizeOf(m_Context.pCertInfo); // 8 (4 on 32bit systems)
int _memleak = _all - _cont1 - _cont2 - _cont3 - _cont4 - _cont5; // 8 (should be 0), (0 on 32bit systems)

if (_memleak != 0)
{
unsafe
{
m_Context.pCertInfo = new IntPtr(m_Context.pCertInfo.ToInt64() + _memleak);
}
}
}

 

Copyright © 2002-2007, The Mentalis.org Team. All rights reserved.
This site is located at http://www.mentalis.org/
Send comments to the webmaster.