Страница: 1 |
|
Вопрос: Помогите, плиз, перевести с MSDN
|
Добавлено: 14.08.05 18:02
|
|
Автор вопроса: avkiev | ICQ: 226072
|
Помогите, плиз, перевести с MSDN следующие описания типов:
typedef struct _CERT_NAME_INFO {
DWORD cRDN;
PCERT_RDN rgRDN;
} CERT_NAME_INFO, *PCERT_NAME_INFO;
typedef struct _CERT_RDN {
DWORD cRDNAttr;
PCERT_RDN_ATTR rgRDNAttr;
} CERT_RDN, *PCERT_RDN;
typedef struct _CERT_RDN_ATTR {
LPSTR pszObjId;
DWORD dwValueType;
CERT_RDN_VALUE_BLOB Value;
} CERT_RDN_ATTR, *PCERT_RDN_ATTR;
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/seccrypto/security/cert_name_info.asp
Не могу понять - как переводить указатели на структуру ?
Делаю так:
Private Type CRYPTOAPI_BLOB
cbData As Long
pbData As String
End Type
Private Type CERT_RDN_ATTR
pszObjId As String
dwValueType As Long
Value As CRYPTOAPI_BLOB
End Type
Private Type CERT_RDN
cRDNAttr As Long
rgRDNAttr As CERT_RDN_ATTR
End Type
Private Type CERT_NAME_INFO
cRDN As Long
rgRDN As CERT_RDN
End Type
Где я ошибаюсь ? Заранее спасибо
Ответить
|
Номер ответа: 3 Автор ответа: avkiev
ICQ: 226072
Вопросов: 48 Ответов: 107
|
Профиль | | #3
|
Добавлено: 15.08.05 13:17
|
Возникла еще одна проблема.
Как быть, если функция требует указатель на структуру и заполняет ее ?
Например:
BOOL WINAPI CryptExportPublicKeyInfo(
HCRYPTPROV hCryptProv,
  WORD dwKeySpec,
  WORD dwCertEncodingType,
PCERT_PUBLIC_KEY_INFO pInfo,
  WORD *pcbInfo
);
...
pInfo
[in] Pointer to a CERT_PUBLIC_KEY_INFO structure to receive the public key information to be exported.
Если в качестве pInfo указывать байтовый массив, то он заполняется, но вот как из него скопировать данные в мою структуру ?
Если в качестве pInfo давать указатель на мою структуру, то возникает ошибка памяти, так как место под мою структуру и ее данные еще не выделены. Не хватает оператора malloc
MSDN делает это так:
// Call CryptExportPublicKeyInfo to get the size of the returned information.
CryptExportPublicKeyInfo( hCryptProv, AT_SIGNATURE, MY_ENCODING_TYPE, [B]NULL[/B], &cbPublicKeyInfo)
// Allocate the necessary memory.
[B]pbPublicKeyInfo = (CERT_PUBLIC_KEY_INFO*)malloc(cbPublicKeyInfo)[/B]
// Call CryptExportPublicKeyInfo to get pbPublicKeyInfo.
CryptExportPublicKeyInfo( hCryptProv, AT_SIGNATURE, MY_ENCODING_TYPE, [B]pbPublicKeyInfo[/B], &cbPublicKeyInfo)
Как перевести этот фрагмент MSDN на VB ?
Ответить
|
Номер ответа: 4 Автор ответа: LamerOnLine
ICQ: 334781088
Вопросов: 108 Ответов: 2822
|
Профиль | | #4
|
Добавлено: 15.08.05 13:45
|
Как быть, если функция требует указатель на структуру и заполняет ее ?
Дать ей указатель на структуру
Если в качестве pInfo указывать байтовый массив
Зачем?
Если в качестве pInfo давать указатель на мою структуру, то возникает ошибка памяти, так как место под мою структуру и ее данные еще не выделены. Не хватает оператора malloc
Ерунда. Если ты объявляешь переменную типа своей структуры, ей автоматически выделяется память.
Скорее всего ты неправильно объявил структуру.
Ответить
|
Номер ответа: 5 Автор ответа: avkiev
ICQ: 226072
Вопросов: 48 Ответов: 107
|
Профиль | | #5
|
Добавлено: 15.08.05 13:55
|
Ерунда. Если ты объявляешь переменную типа своей структуры, ей автоматически выделяется память.
Скорее всего ты неправильно объявил структуру.
Дело в том, что эта структура имеет подструктуры со строковыми данными.
Возьмем простейший случай: структура имеет одно поле типа String. Тогда при инициализации для нее выделится 4 байта (указатель на строку). На самому строку место не выделяется, что приводит к ошибке памяти при попытке записи большого числа данных вызываемой функцией в мою структуру.
Как бы ты описал структуру CERT_PUBLIC_KEY_INFO ?
typedef struct _CERT_PUBLIC_KEY_INFO {
CRYPT_ALGORITHM_IDENTIFIER Algorithm;
CRYPT_BIT_BLOB PublicKey;
} CERT_PUBLIC_KEY_INFO, *PCERT_PUBLIC_KEY_INFO;
typedef struct _CRYPT_ALGORITHM_IDENTIFIER {
LPSTR pszObjId;
CRYPT_OBJID_BLOB Parameters;
} CRYPT_ALGORITHM_IDENTIFIER, *PCRYPT_ALGORITHM_IDENTIFIER;
typedef struct _CRYPTOAPI_BLOB {
  WORD cbData;
BYTE* pbData;
} CRYPT_INTEGER_BLOB, *PCRYPT_INTEGER_BLOB,
CRYPT_OBJID_BLOB, *PCRYPT_OBJID_BLOB,
typedef struct _CRYPT_BIT_BLOB {
  WORD cbData;
BYTE* pbData;
  WORD cUnusedBits;
} CRYPT_BIT_BLOB, *PCRYPT_BIT_BLOB;
Ответить
|
Номер ответа: 10 Автор ответа: avkiev
ICQ: 226072
Вопросов: 48 Ответов: 107
|
Профиль | | #10
|
Добавлено: 15.08.05 16:37
|
Ты лучше приведи свой код с указанием места ошибки.
Option Explicit
'API
Private Declare Function CryptAcquireContext Lib "advapi32.dll" Alias "CryptAcquireContextA" _
  ByRef phProv As Long, ByVal pszContainer As Long, ByVal pszProvider As Long, _
ByVal dwProvType As Long, ByVal dwFlags As Long) As Long
Private Declare Function CryptEncodeObject Lib "crypt32.dll" _
  ByVal dwCertEncodingType As Long, ByVal lpszStructType As Long, ByRef pvStructInfo As Any, _
ByRef pbEncoded As Any, ByRef pcbEncoded As Long) As Long
Private Declare Function CryptExportPublicKeyInfo Lib "crypt32.dll" _
  ByVal hCryptProv As Long, ByVal dwKeySpec As Long, ByVal dwCertEncodingType As Long, _
ByRef pInfo As Any, ByRef pcbInfo As Long) As Long
Private Declare Function CryptSignAndEncodeCertificate Lib "crypt32.dll" _
  ByVal hCryptProv As Long, ByVal dwKeySpec As Long, ByVal dwCertEncodingType As Long, _
ByVal lpszStructType As Long, ByRef pvStructInfo As Any, ByRef pSignatureAlgorithm As Any, _
ByRef pvHashAuxInfo As Any, ByRef pbEncoded As Any, ByRef pcbEncoded As Long) As Long
Private Declare Function CryptReleaseContext Lib "advapi32.dll" ( ByVal hProv As Long, ByVal dwFlags As Long) As Long
'Types
Private Type CRYPTOAPI_BLOB
cbData As Long
pbData As Long
End Type
Private Type CERT_RDN_ATTR
pszObjId As String
dwValueType As Long
Value As CRYPTOAPI_BLOB
End Type
Private Type vBlob
cRDN As Long
rgRDN As Long
End Type
Private Type CRYPT_ALGORITHM_IDENTIFIER
pszObjId As String
Parameters As CRYPTOAPI_BLOB
End Type
Private Type CRYPT_BIT_BLOB
cbData As Long
pbData As Long
cUnusedBits As Long
End Type
Private Type CERT_PUBLIC_KEY_INFO
Algorithm As CRYPT_ALGORITHM_IDENTIFIER
PublicKey As CRYPT_BIT_BLOB
End Type
Private Type FILETIME
dwLowDataTime As Long
dwHighDataTime As Long
End Type
Private Type CERT_INFO
dwVersion As Long
SerialNumber As CRYPTOAPI_BLOB
SignatureAlgorithm As CRYPT_ALGORITHM_IDENTIFIER
Issuer As CRYPTOAPI_BLOB
NotBefore As FILETIME
NotAfter As FILETIME
Subject As CRYPTOAPI_BLOB
SubjectPublicKeyInfo As CERT_PUBLIC_KEY_INFO
IssuerUniqueId As CRYPT_BIT_BLOB
SubjectUniqueId As CRYPT_BIT_BLOB
cExtension As Long
rgExtension As Long
End Type
'Constants
Private Const CERT_V1 As Long = 0
Private Const PROV_RSA_FULL As Long = 1
Private Const AT_SIGNATURE As Long = 2
Private Const CERT_RDN_PRINTABLE_STRING As Long = 4
Private Const X509_CERT_TO_BE_SIGNED As Long = 2
Private Const X509_NAME As Long = 7
Private Const PKCS_7_ASN_ENCODING As Long = &H10000
Private Const X509_ASN_ENCODING As Long = &H1
'Declare
Dim csp As Long
Dim cert As CERT_INFO
Dim EncType As Long
Dim NameInfo As vBlob
Dim EncNameLen As Long
Dim RDN As vBlob, RDN_Attr As CERT_RDN_ATTR
Dim pubKeyInfoLen As Long
Dim pki As CERT_PUBLIC_KEY_INFO
Dim encCertLen As Long
Private Sub Form_Load()
Dim b1(255) As Byte, b2(999) As Byte, b3(999) As Byte
EncType = PKCS_7_ASN_ENCODING Or X509_ASN_ENCODING
CryptAcquireContext csp, 0, 0, PROV_RSA_FULL, 0
'Заполняем поля сертификата, представленного структурой CERT_INFO
cert.dwVersion = CERT_V1
FillBlob cert.SerialNumber, "SerialNumber"
cert.SignatureAlgorithm.pszObjId = StrPtr("1.3.14.3.2.29"
FillBlob cert.SignatureAlgorithm.Parameters, ""
'Кодируем строку, содержащую название издателя сертификата
RDN_Attr.dwValueType = CERT_RDN_PRINTABLE_STRING
RDN_Attr.pszObjId = StrPtr("2.5.4.3"
FillBlob RDN_Attr.Value, "Issuer"
RDN.cRDN = 1: RDN.rgRDN = VarPtr(RDN_Attr)
NameInfo.cRDN = 1: NameInfo.rgRDN = VarPtr(RDN)
CryptEncodeObject EncType, X509_NAME, NameInfo, 0, EncNameLen
CryptEncodeObject EncType, X509_NAME, NameInfo, b1(0), EncNameLen
cert.Issuer.cbData = EncNameLen
cert.Issuer.pbData = b1
'Поля сертификата, содержащие информацию о его владельце
RDN_Attr.dwValueType = CERT_RDN_PRINTABLE_STRING
RDN_Attr.pszObjId = StrPtr("2.5.4.3"
FillBlob RDN_Attr.Value, "Subject"
RDN.cRDN = 1: RDN.rgRDN = VarPtr(RDN_Attr)
NameInfo.cRDN = 1: NameInfo.rgRDN = VarPtr(RDN)
CryptEncodeObject EncType, X509_NAME, NameInfo, 0, EncNameLen
CryptEncodeObject EncType, X509_NAME, NameInfo, b1(0), EncNameLen
cert.Subject.cbData = EncNameLen
cert.Subject.pbData = b1
'Вызвать функцию CryptExportPublicKeyInfo
CryptExportPublicKeyInfo csp, AT_SIGNATURE, EncType, 0, pubKeyInfoLen
'!!!
'В этом месте возникает ошибка памяти.
'Функция CryptExportPublicKeyInfo пытается записать 122 байта в структуру PKI, через размер гораздо меньше
'Не хватает оператора MALLOC или что-то в этом роде
CryptExportPublicKeyInfo csp, AT_SIGNATURE, EncType, pki, pubKeyInfoLen
'!!!
cert.SubjectPublicKeyInfo = pki
CryptSignAndEncodeCertificate csp, AT_SIGNATURE, EncType, X509_CERT_TO_BE_SIGNED, _
cert, cert.SignatureAlgorithm, 0, 0, encCertLen
If encCertLen > 0 Then
MsgBox "Ok ! Size = " & Str(encCertLen)
Else
MsgBox " Error. Size = 0"
End If
CryptReleaseContext csp, 0
End Sub
Private Sub FillBlob(Blob As CRYPTOAPI_BLOB, ByRef v As String)
Blob.pbData = StrPtr(v)
Blob.cbData = Len(v)
End Sub
Ответить
|
Номер ответа: 12 Автор ответа: avkiev
ICQ: 226072
Вопросов: 48 Ответов: 107
|
Профиль | | #12
|
Добавлено: 15.08.05 18:34
|
1. Если ты объявляешь переменную как String - не нужно присваивать ей значение StrPtr. Пытаясь завести API на VB, я понял, что без танцев с бубном тут не обойтись. Вот, шаманю, пытаюсь заставить работать...
Эта структура содержит указатели на буферы данных и длины этих буферов. Вот их ты можешь менять как тебе угодно Вот не могу понять - как. На С все гораздо проще - объявил указатель, выделил память, заполнил ее...
И откуда ты взял 122 байта? У меня вообще вернула требуемую длину - ноль. CryptExportPublicKeyInfo csp, AT_SIGNATURE, EncType, 0, pubKeyInfoLen
У меня возвращает pubKeyInfoLen=122, это зависит от пользователя, но 0 вроде не должен быть.
Глюк тут у тебя Ха, так потому и прошу помощи
Ответить
|
Номер ответа: 13 Автор ответа: LamerOnLine
ICQ: 334781088
Вопросов: 108 Ответов: 2822
|
Профиль | | #13
|
Добавлено: 15.08.05 19:05
|
Пытаясь завести API на VB, я понял, что без танцев с бубном тут не обойтись. Вот, шаманю, пытаюсь заставить работать...
Это некорректно. Так тем более работать не будет.
Вот не могу понять - как. На С все гораздо проще - объявил указатель, выделил память, заполнил ее...
Здесь ты просто объявляешь переменную. Память за тебя выделит компилятор. А для выделения памяти под буффер - массив или строка нужной длины.
У меня возвращает pubKeyInfoLen=122, это зависит от пользователя, но 0 вроде не должен быть.
У меня после исправлений с StrPtr возвращает ноль. Проверь еще раз логику.
Ха, так потому и прошу помощи
Проверь сам еще раз все структуры. Дюжа муторно тут разгребать что ты понаписал
Ответить
|
Страница: 1 |
Поиск по форуму