0

P/Invoke を使用して crypt32.dll からいくつかのメソッドを使用する ASP.NET MVC3 アプリケーションがあります。Windows XP、Windows 7 (32 ビットと 64 ビットの両方)、Windows Server 2003 (32 ビットと 64 ビットの両方) ではすべて正常に動作しますが、Windows Server 2008 R2 x64 でアプリケーションを設定しようとしたときに問題が発生しました。さらに、同じマシンで VS2010 からプロジェクトを実行しようとすると、正常に動作します。サーバーには最新の更新プログラム、IIS 7.5、およびその他の必要なものがすべてインストールされています。

アプリケーションでエラーが発生することはありませんが、「ページが利用できません」またはエラー 503 (アプリケーション プールの停止) が発生するだけです。

イベントビューアで取得したものは次のとおりです。

Faulting application name: w3wp.exe, version: 7.5.7601.17514, time stamp: 0x4ce7a5f8
Faulting module name: CRYPT32.dll, version: 6.1.7601.17514, time stamp: 0x4ce7b841
Exception code: 0xc0000005
Fault offset: 0x00010cf3
Faulting process id: 0xc4c
Faulting application start time: 0x01cd3f0fac5721fb
Faulting application path: C:\Windows\SysWOW64\inetsrv\w3wp.exe
Faulting module path: C:\Windows\syswow64\CRYPT32.dll
Report Id: ee39118a-ab02-11e1-8d06-000c297e9eda

アプリケーション プールは、このアプリケーションによってのみ使用されます。32 ビット アプリケーション、統合されたパイプライン、および正しい .Net バージョンを有効にするように設定されています。プロジェクトは x86 プラットフォーム用にビルドされており (他のすべての可能性を試しても)、必要な DLL をプロジェクトに追加して、[出力ディレクトリにコピー] を [常にコピー] に設定しようとしましたが、何も役に立ちません。

ログを使用して、次の場所で壊れていることがわかりました。

if (!CertGetCertificateContextProperty(pCertContext, CERT_KEY_PROV_INFO_PROP_ID, IntPtr.Zero, ref cbData))
{
    Marshal.ThrowExceptionForHR(Marshal.GetLastWin32Error());
}

DLLImport コード:

[DllImport("crypt32.dll", CharSet = CharSet.Auto, SetLastError = true)]
public static extern bool CertGetCertificateContextProperty(
    IntPtr pCertContext,
    uint dwPropId,
    IntPtr pvData,
    ref uint pcbData
);

問題の原因となる可能性のあるアイデアはありますか?

残りのコードは次のとおりです。

CERT_NAME_BLOB cnbCertificate;
CRYPT_DATA_BLOB certificate;
IntPtr hCertStore = IntPtr.Zero;
IntPtr pCertContext = IntPtr.Zero;
uint cbData = 0;

byte[] encoded = Encode(cert.Subject);

GCHandle pinnedArray = new GCHandle();
pinnedArray = GCHandle.Alloc(cBuffer, GCHandleType.Pinned);

certificate.cbData = cBuffer.Length;
certificate.pbData = pinnedArray.AddrOfPinnedObject();
pinnedArray.Free();
hCertStore = PFXImportCertStore(ref certificate, password, CRYPT_USER_KEYSET | CRYPT_EXPORTABLE);
cnbCertificate.cbData = (uint)encoded.Length;
GCHandle h1;

if (hCertStore != IntPtr.Zero)
{
    try
    {
        h1 = GCHandle.Alloc(encoded, GCHandleType.Pinned);
        cnbCertificate.pbData = h1.AddrOfPinnedObject();

        dataHandle = GCHandle.Alloc(cnbCertificate, GCHandleType.Pinned);
        pCertContext = CertFindCertificateInStore(hCertStore, X509_ASN_ENCODING | PKCS_7_ASN_ENCODING, 0, CERT_FIND_SUBJECT_NAME, dataHandle.AddrOfPinnedObject(), IntPtr.Zero);
        if (h1 != null) h1.Free();
    }
    catch (Exception exp)
    {
        log.Error("Marshall error1: " + exp.Message + " " + Marshal.GetLastWin32Error());
    }
    finally
    {
    }
}

if (!CertGetCertificateContextProperty(pCertContext, CERT_KEY_PROV_INFO_PROP_ID, IntPtr.Zero, ref cbData))
{
    Marshal.ThrowExceptionForHR(Marshal.GetLastWin32Error());
}
4

1 に答える 1

2

ログに例外コード0xc0000005があることに気づきました。これはアクセス違反であり、メソッドに指定したポインターが無効なアドレスを参照していることを意味します。ポインター自体がヌルまたはゼロであるか、ポインターが指す必要のあるCERT_CONTEXT構造体に無効なデータが含まれている可能性があります。

これはASP.NETまたはIISとは関係がなく、コードまたはデータにエラーがあります。おそらく、証明書はそもそも間違っています。

于 2012-06-01T11:35:09.587 に答える