和有什么区别
Dim pCa As IntPtr =
GCHandle.Alloc(New IntPtr, GCHandleType.Pinned).AddrOfPinnedObject
和
Dim pCa as IntPtr = Marshal.AllocHGlobal(4)
Marshal.WriteInt32(pCa, Marshal.AllocHGlobal(4)) ' **stach_st_X509
?
我正在尝试将pkread.c 移植到 .NET 函数,PFXtoPEM()
.
的源代码PFXtoPEM()
可在libCurlVB.NET-native获得。
这是我到目前为止所拥有的:
'''Return Type: int, 0 = success or 1 = failure
'''PFXinfile: String
'''password: String
'''PEMoutfile: String
Public Shared Function PFXtoPEM(ByVal PFXinfile As String, ByVal password As String, ByVal PEMoutfile As String) As Integer
Dim fp As IntPtr = fopen(PFXinfile, "rb")
Dim p12 As IntPtr
Dim cert As X509
Dim ca As stack_st_X509
Dim pPkey As IntPtr = GCHandle.Alloc(New IntPtr, GCHandleType.Pinned).AddrOfPinnedObject
Dim pCert As IntPtr = GCHandle.Alloc(New IntPtr, GCHandleType.Pinned).AddrOfPinnedObject
Dim pCa As IntPtr = GCHandle.Alloc(New IntPtr, GCHandleType.Pinned).AddrOfPinnedObject
If fp.Equals(IntPtr.Zero) Then
MessageBox.Show(String.Concat("Error opening file: ", PFXinfile), "Error Converting PFX to PEM", MessageBoxButtons.OK, MessageBoxIcon.Exclamation)
Return 1
End If
Dim StdErr As IntPtr = freopen("NUL", "a", IntPtr.op_Explicit(__iob_func.ToInt64() + (Marshal.SizeOf(New FILEp) * 2)))
Const errbufSize = 8192
Dim errBuf As IntPtr = Marshal.AllocHGlobal(errbufSize)
ERR_load_crypto_strings()
memset(errBuf, Asc(vbNullChar), errbufSize)
setvbuf(StdErr, errBuf, _IOFBF, errbufSize)
OPENSSL_add_all_algorithms_noconf()
Try
p12 = d2i_PKCS12_fp(fp, IntPtr.Zero)
If p12.Equals(IntPtr.Zero) Then Throw New SEHException("d2i_PKCS12_fp didn't throw but also didn't succeed")
Catch ex As SEHException
ERR_print_errors_fp(StdErr)
MessageBox.Show(String.Concat("Error reading PKCS#12 file. " & vbNewLine, Marshal.PtrToStringAnsi(errBuf)), "Error Converting PFX to PEM", MessageBoxButtons.OK, MessageBoxIcon.Exclamation)
Return 1
End Try
fclose(fp)
Try
PKCS12_parse(p12, password, pPkey, pCert, pCa)
Catch ex As Exception
ERR_print_errors_fp(StdErr)
MessageBox.Show(String.Concat("Error parsing PKCS#12 file, check pfx password. " & vbNewLine, Marshal.PtrToStringAnsi(errBuf)), "Error Converting PFX to PEM", MessageBoxButtons.OK, MessageBoxIcon.Exclamation)
Return 1
End Try
PKCS12_free(p12)
fp = fopen(PEMoutfile, "w")
If fp.Equals(IntPtr.Zero) Then
MessageBox.Show(String.Concat("Error opening file: ", PEMoutfile), "Error Converting PFX to PEM", MessageBoxButtons.OK, MessageBoxIcon.Exclamation)
Return 1
End If
If Not IntPtr.op_Explicit(Marshal.ReadInt32(pPkey)).Equals(IntPtr.Zero) Then
fprintf(fp, "****Private Key****" & vbNewLine)
PEM_write_PrivateKey(fp, IntPtr.op_Explicit(Marshal.ReadInt32(pPkey)), Nothing, Nothing, Nothing, Nothing, Nothing)
End If
If Not IntPtr.op_Explicit(Marshal.ReadInt32(pCert)).Equals(IntPtr.Zero) Then
fprintf(fp, "***User Certificate***" & vbNewLine)
fprintf(fp, "subject=")
fprintf(fp, X509_NAME_oneline(IntPtr.op_Explicit(Marshal.ReadInt32(IntPtr.op_Explicit(Marshal.ReadInt32(Marshal.ReadInt32(pCert)) + 20))), 0, 0))
fprintf(fp, vbNewLine & "issuer=")
fprintf(fp, X509_NAME_oneline(IntPtr.op_Explicit(Marshal.ReadInt32(IntPtr.op_Explicit(Marshal.ReadInt32(Marshal.ReadInt32(pCert)) + 12))), 0, 0))
fprintf(fp, vbNewLine)
PEM_write_X509_AUX(fp, IntPtr.op_Explicit((Marshal.ReadInt32(pCert))))
End If
If Not IntPtr.op_Explicit(Marshal.ReadInt32(pCert)).Equals(IntPtr.Zero) Then
ca = Marshal.PtrToStructure(IntPtr.op_Explicit(Marshal.ReadInt32(pCa)), GetType(stack_st_X509))
fprintf(fp, "****CA Certificates****" & vbNewLine)
For i = 0 To ca.stack.num - 1
cert = Marshal.PtrToStructure(IntPtr.op_Explicit(Marshal.ReadInt32(IntPtr.op_Explicit(ca.stack.data.ToInt32 + 4 * i))), GetType(X509))
Dim certGChandle As GCHandle = GCHandle.Alloc(cert.cert_info, GCHandleType.Pinned)
Dim pCertInfo As IntPtr = certGChandle.AddrOfPinnedObject
fprintf(fp, "subject=")
fprintf(fp, X509_NAME_oneline(IntPtr.op_Explicit(Marshal.ReadInt32(IntPtr.op_Explicit(Marshal.ReadInt32(pCertInfo) + 20))), 0, 0))
fprintf(fp, vbNewLine & "issuer=")
fprintf(fp, X509_NAME_oneline(IntPtr.op_Explicit(Marshal.ReadInt32(IntPtr.op_Explicit(Marshal.ReadInt32(pCertInfo) + 12))), 0, 0))
fprintf(fp, vbNewLine)
PEM_write_X509_AUX(fp, IntPtr.op_Explicit(Marshal.ReadInt32(IntPtr.op_Explicit(ca.stack.data.ToInt32 + 4 * i))))
certGChandle.Free()
Next
End If
fclose(fp)
Marshal.FreeHGlobal(errBuf)
Return 0
End Function
现在,这个函数起作用了,它成功地将 PFX 转换为 PEM,并提供了正确的密码。但是,我不想初始化pPkey
,pCert
和pCa
with GCHandle
。所以我把它改成这样:
'''Return Type: int, 0 = success or 1 = failure
'''PFXinfile: String
'''password: String
'''PEMoutfile: String
Public Shared Function PFXtoPEM(ByVal PFXinfile As String, ByVal password As String, ByVal PEMoutfile As String) As Integer
Dim fp As IntPtr = fopen(PFXinfile, "rb")
Dim p12 As IntPtr
Dim cert As X509
Dim ca As stack_st_X509
Dim pPkey As IntPtr = Marshal.AllocHGlobal(4)
Marshal.WriteInt32(pPkey, Marshal.AllocHGlobal(4)) ' **EVP_PKEY
Dim pCert As IntPtr = Marshal.AllocHGlobal(4)
Marshal.WriteInt32(pCert, Marshal.AllocHGlobal(4)) ' **X509
Dim pCa As IntPtr = Marshal.AllocHGlobal(4)
Marshal.WriteInt32(pCa, Marshal.AllocHGlobal(4)) ' **stach_st_X509
'...
fclose(fp)
Marshal.FreeHGlobal(IntPtr.op_Explicit(Marshal.ReadInt32(pPkey)))
Marshal.FreeHGlobal(IntPtr.op_Explicit(Marshal.ReadInt32(pCert)))
Marshal.FreeHGlobal(IntPtr.op_Explicit(Marshal.ReadInt32(pCa)))
Marshal.FreeHGlobal(pPkey)
Marshal.FreeHGlobal(pCert)
Marshal.FreeHGlobal(pCa)
Marshal.FreeHGlobal(errBuf)
Return 0
End Function
现在这行不通了。PKCS12_parse
,
<DllImport("libeay32.dll", _
SetLastError:=True, _
CallingConvention:=CallingConvention.Cdecl)> _
Public Shared Function PKCS12_parse( _
ByVal p12 As IntPtr, _
<MarshalAs(UnmanagedType.LPStr)> ByVal pass As String, _
ByVal pkey As IntPtr, _
ByVal cert As IntPtr, _
ByVal ca As IntPtr) As Integer
End Function
投掷System.AccessViolationException
但是,这有效:
'''Return Type: int, 0 = success or 1 = failure
'''PFXinfile: String
'''password: String
'''PEMoutfile: String
Public Shared Function PFXtoPEM(ByVal PFXinfile As String, ByVal password As String, ByVal PEMoutfile As String) As Integer
Dim fp As IntPtr = fopen(PFXinfile, "rb")
Dim p12 As IntPtr
Dim cert As X509
Dim ca As stack_st_X509
Dim pPkey As IntPtr = Marshal.AllocHGlobal(4)
Marshal.WriteInt32(pPkey, Marshal.AllocHGlobal(4)) ' **EVP_PKEY
Dim pCert As IntPtr = Marshal.AllocHGlobal(4)
Marshal.WriteInt32(pCert, Marshal.AllocHGlobal(4)) ' **X509
Dim pCa As IntPtr = GCHandle.Alloc(New IntPtr, GCHandleType.Pinned).AddrOfPinnedObject
'...
fclose(fp)
Debug.Print(IntPtr.op_Explicit(Marshal.ReadInt32(pPkey)))
Marshal.FreeHGlobal(IntPtr.op_Explicit(Marshal.ReadInt32(pPkey)))
Marshal.FreeHGlobal(IntPtr.op_Explicit(Marshal.ReadInt32(pCert)))
Marshal.FreeHGlobal(pPkey)
Marshal.FreeHGlobal(pCert)
Marshal.FreeHGlobal(errBuf)
Return 0
End Function