Visual Basic, .NET, ASP, VBScript
 

   
   
     

Форум - Общий форум

Страница: 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


Где я ошибаюсь ? Заранее спасибо

Ответить

  Ответы Всего ответов: 14  

Номер ответа: 1
Автор ответа:
 GSerg



Вопросов: 0
Ответов: 1876


 Профиль | | #1 Добавлено: 14.08.05 18:27
Переводить как long.
Объявить ещё одну переменную типа указываемой структуры.
В первую структуру присвоить varptr на вторую.

Ответить

Номер ответа: 2
Автор ответа:
 avkiev



ICQ: 226072 

Вопросов: 48
Ответов: 107
 Профиль | | #2 Добавлено: 14.08.05 18:38
Большое спасибо.
Все получилось

Ответить

Номер ответа: 3
Автор ответа:
 avkiev



ICQ: 226072 

Вопросов: 48
Ответов: 107
 Профиль | | #3 Добавлено: 15.08.05 13:17
Возникла еще одна проблема.
Как быть, если функция требует указатель на структуру и заполняет ее ?
Например:

BOOL WINAPI CryptExportPublicKeyInfo(
  HCRYPTPROV hCryptProv,
  ;DWORD dwKeySpec,
  ;DWORD dwCertEncodingType,
  PCERT_PUBLIC_KEY_INFO pInfo,
  ;DWORD *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 {
  ;DWORD    cbData;
  BYTE*    pbData;
} CRYPT_INTEGER_BLOB,    *PCRYPT_INTEGER_BLOB,
  CRYPT_OBJID_BLOB,    *PCRYPT_OBJID_BLOB,

typedef struct _CRYPT_BIT_BLOB {
  ;DWORD             cbData;
  BYTE*             pbData;
  ;DWORD             cUnusedBits;
} CRYPT_BIT_BLOB,    *PCRYPT_BIT_BLOB;

Ответить

Номер ответа: 6
Автор ответа:
 LamerOnLine



ICQ: 334781088 

Вопросов: 108
Ответов: 2822
 Профиль | | #6 Добавлено: 15.08.05 14:00
Где ты тут видишь строку? Я вижу только указатель на нее, который ты сам должен дать.
Я бы записал примерно так (писал на скорую руку, проверь)

Private Type CRYPT_BIT_BLOB
    cbData As Long
    pbData As Long
    cUnusedBits As Long
End Type

Private Type CRYPT_ALGORITHM_IDENTIFIER
    pszObjId As String
    Parameters As CRYPT_BIT_BLOB
End Type

Private Type CERT_PUBLIC_KEY_INFO
    Algorithm As CRYPT_ALGORITHM_IDENTIFIER
    PublicKey As CRYPT_BIT_BLOB
End Type

Dim Crypt As CERT_PUBLIC_KEY_INFO

Ответить

Номер ответа: 7
Автор ответа:
 LamerOnLine



ICQ: 334781088 

Вопросов: 108
Ответов: 2822
 Профиль | | #7 Добавлено: 15.08.05 14:02
Если уж так напрягает указатель на строку - замени его на Long и передавай StrPtr.

Ответить

Номер ответа: 8
Автор ответа:
 avkiev



ICQ: 226072 

Вопросов: 48
Ответов: 107
 Профиль | | #8 Добавлено: 15.08.05 14:38
Все равно не работает. Или ошибки памяти или возвращает 0 там где его быть не должно.

Все, что я хочу сделать - это перевести на VB следующий пример:
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/seccrypto/security/example_c_program_making_a_certificate_request.asp

На Delphi перевел легко, а вот с VB - затык.
Никто этим не занимался ?

Ответить

Номер ответа: 9
Автор ответа:
 LamerOnLine



ICQ: 334781088 

Вопросов: 108
Ответов: 2822
 Профиль | | #9 Добавлено: 15.08.05 15:20
Ты лучше приведи свой код с указанием места ошибки.

Ответить

Номер ответа: 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

Ответить

Номер ответа: 11
Автор ответа:
 LamerOnLine



ICQ: 334781088 

Вопросов: 108
Ответов: 2822
 Профиль | | #11 Добавлено: 15.08.05 17:29
1. Если ты объявляешь переменную как String - не нужно присваивать ей значение StrPtr.
2. Размер структуры PCERT_PUBLIC_KEY_INFO жестко определен, ты не можешь изменить его. Она не содержит ни строк ни массивов. Эта структура содержит указатели на буферы данных и длины этих буферов. Вот их ты можешь менять как тебе угодно. Просто задавай массив произвольной длины as byte и присваивай указатель. Но тут у тебя косяк где-то в другом.
И откуда ты взял 122 байта? У меня вообще вернула требуемую длину - ноль. Глюк тут у тебя.

Ответить

Номер ответа: 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 возвращает ноль. Проверь еще раз логику.

Ха, так потому и прошу помощи

Проверь сам еще раз все структуры. Дюжа муторно тут разгребать что ты понаписал :)

Ответить

Номер ответа: 14
Автор ответа:
 avkiev



ICQ: 226072 

Вопросов: 48
Ответов: 107
 Профиль | | #14 Добавлено: 15.08.05 19:12
Делаю так:
  CryptExportPublicKeyInfo csp, AT_SIGNATURE, EncType, 0, pubKeyInfoLen
  CryptExportPublicKeyInfo csp, AT_SIGNATURE, EncType, b3(0), pubKeyInfoLen

В буфере B3 возвращается 122 байта. Это и сама структура CERT_PUBLIC_KEY_INFO и данные ее подструктур.
На С я бы сказал так:
CERT_PUBLIC_KEY_INFO *pki;
pki = b3;

и работал бы со структурой на которую указывает PKI.

Как этот трюк проделать на VB ?

Ответить

Страница: 1 |

Поиск по форуму



© Copyright 2002-2011 VBNet.RU | Пишите нам