Функция CryptEncodeObjectEx (wincrypt.h)

Функция CryptEncodeObjectEx кодирует структуру типа, указанного значением параметра lpszStructType . Эта функция обеспечивает значительное повышение производительности по сравнению с CryptEncodeObject за счет поддержки выделения памяти со значением CRYPT_ENCODE_ALLOC_FLAG .

Синтаксис

BOOL CryptEncodeObjectEx(
  [in]      DWORD              dwCertEncodingType,
  [in]      LPCSTR             lpszStructType,
  [in]      const void         *pvStructInfo,
  [in]      DWORD              dwFlags,
  [in]      PCRYPT_ENCODE_PARA pEncodePara,
  [out]     void               *pvEncoded,
  [in, out] DWORD              *pcbEncoded
);

Параметры

[in] dwCertEncodingType

Тип кодирования сертификата и тип кодирования сообщений, используемый для кодирования объекта. Этот параметр может быть сочетанием одного или нескольких из следующих значений.

Значение Значение
PKCS_7_ASN_ENCODING
65536 (0x10000)
Задает кодировку сообщений PKCS 7.
X509_ASN_ENCODING
1 (0x1)
Задает кодировку сертификата X.509.

[in] lpszStructType

Указатель на идентификатор объекта (OID), определяющий тип структуры. Если слово высокого порядка параметра lpszStructType равно нулю, слово нижнего порядка задает целочисленный идентификатор для типа указанной структуры. В противном случае этот параметр является указателем на строку, завершающуюся значением NULL, которая содержит строковое представление объекта OID.

Дополнительные сведения о строках идентификаторов объектов, их предопределенных константах и соответствующих структурах см. в разделе Константы для CryptEncodeObject и CryptDecodeObject.

[in] pvStructInfo

Указатель на структуру для кодирования. Структура должна иметь тип, заданный lpszStructType.

[in] dwFlags

Задает параметры для кодировки. Этот параметр может быть равен нулю или сочетанию одного или нескольких из следующих значений.

Значение Значение
CRYPT_ENCODE_ALLOC_FLAG
32768 (0x8000)
Вызываемая функция кодирования выделяет память для закодированных байтов. Указатель на выделенные байты возвращается в pvEncoded.
CRYPT_ENCODE_ENABLE_PUNYCODE_FLAG
131072 (0x20000)
Этот флаг применим для включения кодирования строковых значений Юникода в Punycode. Дополнительные сведения см. в подразделе "Примечания".

Windows Server 2008, Windows Vista, Windows Server 2003 и Windows XP: Этот флаг не поддерживается.

CRYPT_UNICODE_NAME_ENCODE_DISABLE_CHECK_TYPE_FLAG
1073741824 (0x40000000)
Этот флаг применяется при кодировании X509_UNICODE_NAME, X509_UNICODE_NAME_VALUE или X509_UNICODE_ANY_STRING. Если этот флаг установлен, символы не проверяются, чтобы определить, являются ли они допустимыми для указанного типа значения.
CRYPT_UNICODE_NAME_ENCODE_ENABLE_T61_UNICODE_FLAG
2147483648 (0x80000000)
Этот флаг применим при кодировании X509_UNICODE_NAME. Если этот флаг установлен и все символы Юникода имеют <значение = 0xFF, CERT_RDN_T61_STRING выбирается вместо CERT_RDN_UNICODE_STRING.
CRYPT_UNICODE_NAME_ENCODE_ENABLE_UTF8_UNICODE_FLAG
536870912 (0x20000000)
Этот флаг применим при кодировании X509_UNICODE_NAME. Если этот параметр задан, вместо CERT_RDN_UNICODE_STRING выбирается CERT_RDN_UTF8_STRING.
CRYPT_UNICODE_NAME_ENCODE_FORCE_UTF8_UNICODE_FLAG
268435456 (0x10000000)
Этот флаг применим при кодировании X509_UNICODE_NAME. Если этот параметр задан, CERT_RDN_UTF8_STRING выбирается вместо CERT_RDN_PRINTABLE_STRING для типов строк каталога. Кроме того, этот флаг позволяет CRYPT_UNICODE_NAME_ENCODE_ENABLE_UTF8_UNICODE_FLAG.

[in] pEncodePara

Указатель на структуру CRYPT_ENCODE_PARA , содержащую сведения о кодировке. Этот параметр может принимать значение NULL.

Если pEncodePara или элемент pfnAllocpEncodePara имеет значение NULL, то для выделения используется LocalAlloc , а для освобождения памяти необходимо вызвать LocalFree .

Если оба элемента pEncodePara и pfnAllocpEncodePara не имеют значения NULL, то для выделения вызывается функция, на которую указывает элемент pfnAllocструктуры CRYPT_ENCODE_PARA , на которую указывает pEncodePara . Для освобождения памяти необходимо вызвать функцию, на которую указывает член pfnFreepEncodePara .

[out] pvEncoded

Указатель на буфер для получения закодированной структуры. Размер этого буфера указывается в параметре pcbEncoded . Если указанный буфер недостаточно велик для получения декодированных структур, функция задает код ERROR_MORE_DATA и сохраняет требуемый размер буфера в байтах в переменной, на которую указывает pcbEncoded.

Этот параметр может иметь значение NULL , чтобы получить размер буфера для выделения памяти. Дополнительные сведения см. в разделе Извлечение данных неизвестной длины.

Если dwFlags содержит флаг CRYPT_ENCODE_ALLOC_FLAG , pvEncoded не является указателем на буфер, а является адресом указателя на буфер. Так как память выделяется внутри функции, а указатель хранится в pvEncoded, параметр pvEncoded не может иметь значение NULL.

[in, out] pcbEncoded

Указатель на переменную DWORD , содержащую размер (в байтах) буфера, на который указывает параметр pvEncoded . При возврате функции переменная, на которую указывает параметр pcbEncoded , содержит количество выделенных закодированных байтов, хранящихся в буфере.

Если dwFlags содержит флаг CRYPT_ENCODE_ALLOC_FLAG , pcbEncoded — это адрес указателя на обновляемое значение DWORD .

Примечание При обработке данных, возвращаемых в буфере, приложения должны использовать фактический размер возвращаемых данных. Фактический размер может быть немного меньше размера буфера, указанного на входных данных. (На входных данных размеры буфера обычно указываются достаточно большими, чтобы убедиться, что в буфере помещаются самые большие выходные данные.) В выходных данных переменная, на которую указывает этот параметр, обновляется с учетом фактического размера данных, скопированных в буфер.
 

Возвращаемое значение

Возвращает ненулевое значение при успешном выполнении или нулевое значение в противном случае.

Для получения дополнительных сведений об ошибке вызовите Метод GetLastError. В следующей таблице показаны некоторые возможные коды ошибок, которые могут быть возвращены из GetLastError при сбое CryptEncodeObjectEx .

Код возврата Описание
CRYPT_E_BAD_ENCODE
При кодировании возникла ошибка.
ERROR_FILE_NOT_FOUND
Не удалось найти функцию кодирования для указанных dwCertEncodingType и lpszStructType.
ERROR_MORE_DATA
Если буфер, заданный параметром pvEncoded , недостаточно велик для хранения возвращаемых данных, функция задает код ERROR_MORE_DATA и сохраняет требуемый размер буфера в байтах в переменной, на которую указывает pcbEncoded.
 

Если функция завершается сбоем, GetLastError может вернуть ошибку кодирования и декодирования абстрактной синтаксической нотации 1 (ASN.1). Сведения об этих ошибках см. в разделе Кодирование и декодирование возвращаемых значений ASN.1.

Комментарии

При кодировании криптографического объекта с помощью предпочтительной функции CryptEncodeObjectEx включается завершающий символ NULL . При декодировании с помощью предпочтительной функции CryptDecodeObjectEx завершающий символ NULL не сохраняется.

CryptEncodeObjectEx сначала ищет устанавливаемую функцию расширенного кодирования. Если функция расширенного кодирования не найдена, будет найдена старая, нерасширяемая, устанавливаемая функция.

Если прямая кодировка IA5String объекта невозможна, можно указать кодировку Punycode, задав для параметра dwFlagзначение CRYPT_ENCODE_ENABLE_PUNYCODE_FLAG . Установка флага CRYPT_ENCODE_ENABLE_PUNYCODE_FLAG имеет различные эффекты в зависимости от типа закодированной структуры, заданного значением параметра lpszStructType .

Каждая константа в приведенном ниже списке имеет связанный тип структуры, на который указывает параметр pvStructInfo . Структура, на которая прямо или косвенно указывает, имеет ссылку на CERT_ALT_NAME_ENTRY структуру.

  • X509_ALTERNATE_NAME
  • szOID_AUTHORITY_INFO_ACCESS
  • X509_AUTHORITY_INFO_ACCESS
  • X509_AUTHORITY_KEY_ID2
  • szOID_AUTHORITY_KEY_IDENTIFIER2
  • szOID_CRL_DIST_POINTS
  • X509_CRL_DIST_POINTS
  • szOID_CROSS_CERT_DIST_POINTS
  • X509_CROSS_CERT_DIST_POINTS
  • szOID_ISSUER_ALT_NAME
  • szOID_ISSUER_ALT_NAME2
  • szOID_ISSUING_DIST_POINT
  • X509_ISSUING_DIST_POINT
  • szOID_NAME_CONSTRAINTS
  • X509_NAME_CONSTRAINTS
  • szOID_NEXT_UPDATE_LOCATION
  • OCSP_REQUEST
  • zOID_SUBJECT_ALT_NAME
  • szOID_SUBJECT_ALT_NAME2
Флаг CRYPT_ENCODE_ENABLE_PUNYCODE_FLAG в сочетании со значением члена dwAltNameChoice структуры CERT_ALT_NAME_ENTRY определяет способ кодирования строк.
dwAltNameChoice Действие
CERT_ALT_NAME_DNS_NAME Если имя узла содержит символы Юникода за пределами набора символов ASCII, имя узла сначала кодируется в Punycode, а затем кодируется как строка IA5String .
CERT_ALT_NAME_RFC822_NAME Если часть имени узла адреса электронной почты содержит символы Юникода за пределами набора символов ASCII, часть имени узла адреса электронной почты кодируется в Punycode. Затем результирующий адрес электронной почты кодируется как строка IA5String .
CERT_ALT_NAME_URL Если имя узла сервера URI содержит символы Юникода за пределами набора символов ASCII, то часть URI имени узла кодируется в Punycode. Затем результирующий URI экранируется, а URL-адрес кодируется как строка IA5String .
 

Каждая константа в приведенном ниже списке имеет связанный тип структуры, на который указывает параметр pvStructInfo . Прямо или косвенно указанная структура имеет ссылку на CERT_HASHED_URL структуру.

  • szOID_BIOMETRIC_EXT
  • X509_BIOMETRIC_EXT
  • szOID_LOGOTYPE_EXT
  • X509_LOGOTYPE_EXT
При кодировании значения структуры CERT_HASHED_URL , если имя узла сервера URI содержит символы Юникода за пределами набора символов ASCII и задано CRYPT_ENCODE_ENABLE_PUNYCODE_FLAG , часть URI узла кодируется в Punycode. Затем результирующий URI экранируется, а URL-адрес кодируется как строка IA5String .

Каждая константа X509_UNICODE_NAME в приведенном ниже списке имеет связанный тип структуры, на который указывает параметр pvStructInfo .

  • X509_UNICODE_NAME
Если для элемента pszObjIdструктуры CERT_RDN_ATTR задано значение szOID_RSA_emailAddr , а адрес электронной почты в элементе Value содержит символы Юникода за пределами набора символов ASCII, часть адреса электронной почты с именем узла кодируется в Punycode. Затем результирующий адрес электронной почты кодируется как строка IA5String .

Во всех случаях кодирование имени узла в Punycode выполняется по метке.

Примеры

В следующем примере показано инициализация и кодирование структуры X509_NAME с помощью CryptEncodeObjectEx. Пример, включающий полный контекст для этого примера, см. в разделе Пример программы C: кодирование и декодирование ASN.1.

#include <windows.h>
#include <stdio.h>
#include <Wincrypt.h>
#pragma comment(lib, "crypt32.lib")


#define MY_TYPE (X509_ASN_ENCODING)

void main()
{

//#define moved

//--------------------------------------------------------------------
//   Declare and initialize local variables.

char *Cert_Sub_Name ="Test User Name";

//--------------------------------------------------------------------
// Initialize a single RDN structure.

CERT_RDN_ATTR rgNameAttr = 
{
   "2.5.4.3",                      // The OID
   CERT_RDN_PRINTABLE_STRING,      // Type of string
   (DWORD)strlen(Cert_Sub_Name)+1, // String length including
                                   //  the terminating null character
   (BYTE *)Cert_Sub_Name           // Pointer to the string 
};
//--------------------------------------------------------------------
// Declare and initialize a structure to include
// the array of RDN structures.

CERT_RDN rgRDN[] = 
{
   1,               // The number of elements in the array
   &rgNameAttr      // Pointer to the array
};

//--------------------------------------------------------------------
//  Declare and initialize a CERT_NAME_INFO 
//  structure that includes a CERT_RND.

CERT_NAME_INFO CertName = 
{
    1,          // The number of elements in the CERT_RND's array
    rgRDN
};

//--------------------------------------------------------------------
//  Declare additional variables.

DWORD cbEncoded;              // Variable to hold the
                              //  length of the encoded string
BYTE *pbEncoded;              // Variable to hold a pointer to the 
                              //  encoded buffer
//--------------------------------------------------------------------
// Call CrypteEncodeObjectEx to get 
// length to allocate for pbEncoded.

if( CryptEncodeObjectEx(
     MY_TYPE,        // The encoding/decoding type
     X509_NAME,    
     &CertName,
     0,                 
     NULL, 
     NULL,
     &cbEncoded))    // Fill in the length needed for
                     // the encoded buffer.
{
     printf("The number of bytes needed is %d \n",cbEncoded);
}
else
{
     printf("The first call to the function failed.\n");
     exit(1);
}

if( pbEncoded = (BYTE*)malloc(cbEncoded))
{
     printf("Memory for pvEncoded has been allocated.\n");
}
else
{
    printf("Memory allocation failed.\n");
    exit(1);
}

if(CryptEncodeObjectEx(
     MY_TYPE,
     X509_NAME,
     &CertName,
     0,
     NULL, 
     pbEncoded,
     &cbEncoded))
{
     printf("The structure has been encoded.\n");
}
else
{
     printf("Encoding failed.");
     exit(1);
}
// Free allocated memory when done.
// ...
if(pbEncoded)
{
    free(pbEncoded);
}


Требования

Требование Значение
Минимальная версия клиента Windows XP [классические приложения | Приложения UWP]
Минимальная версия сервера Windows Server 2003 [классические приложения | Приложения UWP]
Целевая платформа Windows
Header wincrypt.h
Библиотека Crypt32.lib
DLL Crypt32.dll

См. также раздел

CryptDecodeObject

CryptDecodeObjectEx

CryptEncodeObject

Функции кодирования и декодирования объектов