You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
12863 lines
411 KiB
12863 lines
411 KiB
|
|
//+-------------------------------------------------------------------------
|
|
//
|
|
// Microsoft Windows
|
|
//
|
|
// Copyright (C) Microsoft Corporation, 1996 - 1999
|
|
//
|
|
// File: wincert.cpp
|
|
//
|
|
// Contents: Certificate, Certificate Revocation List (CRL),
|
|
// Certificate Request and Certificate Name
|
|
// Encode/Decode APIs
|
|
//
|
|
// ASN.1 implementation uses the ASN1 compiler.
|
|
//
|
|
// Functions: CryptEncodeObject
|
|
// CryptDecodeObject
|
|
// CryptEncodeObjectEx
|
|
// CryptDecodeObjectEx
|
|
//
|
|
// History: 29-Feb-96 philh created
|
|
// 20-Jan-98 philh added "Ex" version
|
|
//
|
|
//--------------------------------------------------------------------------
|
|
|
|
|
|
#include "global.hxx"
|
|
#include <dbgdef.h>
|
|
|
|
#ifndef OSS_CRYPT_ASN1
|
|
#define ASN1_SUPPORTS_UTF8_TAG 1
|
|
#endif // OSS_CRYPT_ASN1
|
|
|
|
// All the *pvInfo extra stuff needs to be aligned
|
|
#define INFO_LEN_ALIGN(Len) ((Len + 7) & ~7)
|
|
|
|
static const BYTE NullDer[2] = {0x05, 0x00};
|
|
static const CRYPT_OBJID_BLOB NullDerBlob = {2, (BYTE *)&NullDer[0]};
|
|
|
|
HCRYPTASN1MODULE hX509Asn1Module;
|
|
|
|
HCRYPTOIDFUNCSET hX509EncodeFuncSet;
|
|
HCRYPTOIDFUNCSET hX509DecodeFuncSet;
|
|
HCRYPTOIDFUNCSET hX509EncodeExFuncSet;
|
|
HCRYPTOIDFUNCSET hX509DecodeExFuncSet;
|
|
|
|
|
|
//+-------------------------------------------------------------------------
|
|
// Function: GetEncoder/GetDecoder
|
|
//
|
|
// Synopsis: Initialize thread local storage for the asn libs
|
|
//
|
|
// Returns: pointer to an initialized Asn1 encoder/decoder data
|
|
// structures
|
|
//--------------------------------------------------------------------------
|
|
static inline ASN1encoding_t GetEncoder(void)
|
|
{
|
|
return I_CryptGetAsn1Encoder(hX509Asn1Module);
|
|
}
|
|
static inline ASN1decoding_t GetDecoder(void)
|
|
{
|
|
return I_CryptGetAsn1Decoder(hX509Asn1Module);
|
|
}
|
|
|
|
typedef BOOL (WINAPI *PFN_ENCODE_FUNC) (
|
|
IN DWORD dwCertEncodingType,
|
|
IN LPCSTR lpszStructType,
|
|
IN const void *pvStructInfo,
|
|
OUT OPTIONAL BYTE *pbEncoded,
|
|
IN OUT DWORD *pcbEncoded
|
|
);
|
|
|
|
typedef BOOL (WINAPI *PFN_DECODE_FUNC) (
|
|
IN DWORD dwCertEncodingType,
|
|
IN LPCSTR lpszStructType,
|
|
IN const BYTE *pbEncoded,
|
|
IN DWORD cbEncoded,
|
|
IN DWORD dwFlags,
|
|
OUT OPTIONAL void *pvStructInfo,
|
|
IN OUT DWORD *pcbStructInfo
|
|
);
|
|
|
|
typedef BOOL (WINAPI *PFN_ENCODE_EX_FUNC) (
|
|
IN DWORD dwCertEncodingType,
|
|
IN LPCSTR lpszStructType,
|
|
IN const void *pvStructInfo,
|
|
IN DWORD dwFlags,
|
|
IN OPTIONAL PCRYPT_ENCODE_PARA pEncodePara,
|
|
OUT OPTIONAL void *pvEncoded,
|
|
IN OUT DWORD *pcbEncoded
|
|
);
|
|
|
|
typedef BOOL (WINAPI *PFN_DECODE_EX_FUNC) (
|
|
IN DWORD dwCertEncodingType,
|
|
IN LPCSTR lpszStructType,
|
|
IN const BYTE *pbEncoded,
|
|
IN DWORD cbEncoded,
|
|
IN DWORD dwFlags,
|
|
IN OPTIONAL PCRYPT_DECODE_PARA pDecodePara,
|
|
OUT OPTIONAL void *pvStructInfo,
|
|
IN OUT DWORD *pcbStructInfo
|
|
);
|
|
|
|
//+-------------------------------------------------------------------------
|
|
// ASN1 X509 v3 ASN.1 Encode / Decode functions
|
|
//--------------------------------------------------------------------------
|
|
BOOL WINAPI Asn1CSPProviderEncodeEx(
|
|
IN DWORD dwCertEncodingType,
|
|
IN LPCSTR lpszStructType,
|
|
IN PCRYPT_CSP_PROVIDER pCSPProvider,
|
|
IN DWORD dwFlags,
|
|
IN OPTIONAL PCRYPT_ENCODE_PARA pEncodePara,
|
|
OUT OPTIONAL void *pvEncoded,
|
|
IN OUT DWORD *pcbEncoded
|
|
);
|
|
|
|
BOOL WINAPI Asn1CSPProviderDecodeEx(
|
|
IN DWORD dwCertEncodingType,
|
|
IN LPCSTR lpszStructType,
|
|
IN const BYTE *pbEncoded,
|
|
IN DWORD cbEncoded,
|
|
IN DWORD dwFlags,
|
|
IN OPTIONAL PCRYPT_DECODE_PARA pDecodePara,
|
|
OUT OPTIONAL void *pvStructInfo,
|
|
IN OUT DWORD *pcbStructInfo
|
|
);
|
|
|
|
BOOL WINAPI Asn1NameValueEncodeEx(
|
|
IN DWORD dwCertEncodingType,
|
|
IN LPCSTR lpszStructType,
|
|
IN PCRYPT_ENROLLMENT_NAME_VALUE_PAIR pNameValue,
|
|
IN DWORD dwFlags,
|
|
IN OPTIONAL PCRYPT_ENCODE_PARA pEncodePara,
|
|
OUT OPTIONAL void *pvEncoded,
|
|
IN OUT DWORD *pcbEncoded
|
|
);
|
|
|
|
BOOL WINAPI Asn1NameValueDecodeEx(
|
|
IN DWORD dwCertEncodingType,
|
|
IN LPCSTR lpszStructType,
|
|
IN const BYTE *pbEncoded,
|
|
IN DWORD cbEncoded,
|
|
IN DWORD dwFlags,
|
|
IN OPTIONAL PCRYPT_DECODE_PARA pDecodePara,
|
|
OUT OPTIONAL void *pvStructInfo,
|
|
IN OUT DWORD *pcbStructInfo
|
|
);
|
|
|
|
BOOL WINAPI Asn1X509CertInfoEncodeEx(
|
|
IN DWORD dwCertEncodingType,
|
|
IN LPCSTR lpszStructType,
|
|
IN PCERT_INFO pInfo,
|
|
IN DWORD dwFlags,
|
|
IN OPTIONAL PCRYPT_ENCODE_PARA pEncodePara,
|
|
OUT OPTIONAL void *pvEncoded,
|
|
IN OUT DWORD *pcbEncoded
|
|
);
|
|
BOOL WINAPI Asn1X509CertInfoDecodeEx(
|
|
IN DWORD dwCertEncodingType,
|
|
IN LPCSTR lpszStructType,
|
|
IN const BYTE *pbEncoded,
|
|
IN DWORD cbEncoded,
|
|
IN DWORD dwFlags,
|
|
IN OPTIONAL PCRYPT_DECODE_PARA pDecodePara,
|
|
OUT OPTIONAL void *pvStructInfo,
|
|
IN OUT DWORD *pcbStructInfo
|
|
);
|
|
BOOL WINAPI Asn1X509CrlInfoEncodeEx(
|
|
IN DWORD dwCertEncodingType,
|
|
IN LPCSTR lpszStructType,
|
|
IN PCRL_INFO pInfo,
|
|
IN DWORD dwFlags,
|
|
IN OPTIONAL PCRYPT_ENCODE_PARA pEncodePara,
|
|
OUT OPTIONAL void *pvEncoded,
|
|
IN OUT DWORD *pcbEncoded
|
|
);
|
|
BOOL WINAPI Asn1X509CrlInfoDecodeEx(
|
|
IN DWORD dwCertEncodingType,
|
|
IN LPCSTR lpszStructType,
|
|
IN const BYTE *pbEncoded,
|
|
IN DWORD cbEncoded,
|
|
IN DWORD dwFlags,
|
|
IN OPTIONAL PCRYPT_DECODE_PARA pDecodePara,
|
|
OUT OPTIONAL void *pvStructInfo,
|
|
IN OUT DWORD *pcbStructInfo
|
|
);
|
|
BOOL WINAPI Asn1X509CertRequestInfoEncodeEx(
|
|
IN DWORD dwCertEncodingType,
|
|
IN LPCSTR lpszStructType,
|
|
IN PCERT_REQUEST_INFO pInfo,
|
|
IN DWORD dwFlags,
|
|
IN OPTIONAL PCRYPT_ENCODE_PARA pEncodePara,
|
|
OUT OPTIONAL void *pvEncoded,
|
|
IN OUT DWORD *pcbEncoded
|
|
);
|
|
BOOL WINAPI Asn1X509CertRequestInfoDecodeEx(
|
|
IN DWORD dwCertEncodingType,
|
|
IN LPCSTR lpszStructType,
|
|
IN const BYTE *pbEncoded,
|
|
IN DWORD cbEncoded,
|
|
IN DWORD dwFlags,
|
|
IN OPTIONAL PCRYPT_DECODE_PARA pDecodePara,
|
|
OUT OPTIONAL void *pvStructInfo,
|
|
IN OUT DWORD *pcbStructInfo
|
|
);
|
|
|
|
BOOL WINAPI Asn1X509KeygenRequestInfoEncodeEx(
|
|
IN DWORD dwCertEncodingType,
|
|
IN LPCSTR lpszStructType,
|
|
IN PCERT_KEYGEN_REQUEST_INFO pInfo,
|
|
IN DWORD dwFlags,
|
|
IN OPTIONAL PCRYPT_ENCODE_PARA pEncodePara,
|
|
OUT OPTIONAL void *pvEncoded,
|
|
IN OUT DWORD *pcbEncoded
|
|
);
|
|
BOOL WINAPI Asn1X509KeygenRequestInfoDecodeEx(
|
|
IN DWORD dwCertEncodingType,
|
|
IN LPCSTR lpszStructType,
|
|
IN const BYTE *pbEncoded,
|
|
IN DWORD cbEncoded,
|
|
IN DWORD dwFlags,
|
|
IN OPTIONAL PCRYPT_DECODE_PARA pDecodePara,
|
|
OUT OPTIONAL void *pvStructInfo,
|
|
IN OUT DWORD *pcbStructInfo
|
|
);
|
|
|
|
BOOL WINAPI Asn1X509SignedContentEncodeEx(
|
|
IN DWORD dwCertEncodingType,
|
|
IN LPCSTR lpszStructType,
|
|
IN PCERT_SIGNED_CONTENT_INFO pInfo,
|
|
IN DWORD dwFlags,
|
|
IN OPTIONAL PCRYPT_ENCODE_PARA pEncodePara,
|
|
OUT OPTIONAL void *pvEncoded,
|
|
IN OUT DWORD *pcbEncoded
|
|
);
|
|
BOOL WINAPI Asn1X509SignedContentDecodeEx(
|
|
IN DWORD dwCertEncodingType,
|
|
IN LPCSTR lpszStructType,
|
|
IN const BYTE *pbEncoded,
|
|
IN DWORD cbEncoded,
|
|
IN DWORD dwFlags,
|
|
IN OPTIONAL PCRYPT_DECODE_PARA pDecodePara,
|
|
OUT OPTIONAL void *pvStructInfo,
|
|
IN OUT DWORD *pcbStructInfo
|
|
);
|
|
|
|
BOOL WINAPI Asn1X509NameInfoEncodeEx(
|
|
IN DWORD dwCertEncodingType,
|
|
IN LPCSTR lpszStructType,
|
|
IN PCERT_NAME_INFO pInfo,
|
|
IN DWORD dwFlags,
|
|
IN OPTIONAL PCRYPT_ENCODE_PARA pEncodePara,
|
|
OUT OPTIONAL void *pvEncoded,
|
|
IN OUT DWORD *pcbEncoded
|
|
);
|
|
BOOL WINAPI Asn1X509NameInfoDecodeEx(
|
|
IN DWORD dwCertEncodingType,
|
|
IN LPCSTR lpszStructType,
|
|
IN const BYTE *pbEncoded,
|
|
IN DWORD cbEncoded,
|
|
IN DWORD dwFlags,
|
|
IN OPTIONAL PCRYPT_DECODE_PARA pDecodePara,
|
|
OUT OPTIONAL void *pvStructInfo,
|
|
IN OUT DWORD *pcbStructInfo
|
|
);
|
|
BOOL WINAPI Asn1X509NameValueEncodeEx(
|
|
IN DWORD dwCertEncodingType,
|
|
IN LPCSTR lpszStructType,
|
|
IN PCERT_NAME_VALUE pInfo,
|
|
IN DWORD dwFlags,
|
|
IN OPTIONAL PCRYPT_ENCODE_PARA pEncodePara,
|
|
OUT OPTIONAL void *pvEncoded,
|
|
IN OUT DWORD *pcbEncoded
|
|
);
|
|
BOOL WINAPI Asn1X509NameValueDecodeEx(
|
|
IN DWORD dwCertEncodingType,
|
|
IN LPCSTR lpszStructType,
|
|
IN const BYTE *pbEncoded,
|
|
IN DWORD cbEncoded,
|
|
IN DWORD dwFlags,
|
|
IN OPTIONAL PCRYPT_DECODE_PARA pDecodePara,
|
|
OUT OPTIONAL void *pvStructInfo,
|
|
IN OUT DWORD *pcbStructInfo
|
|
);
|
|
|
|
//+-------------------------------------------------------------------------
|
|
// ASN1 ASN.1 X509 Certificate Extensions Encode / Decode functions
|
|
//--------------------------------------------------------------------------
|
|
BOOL WINAPI Asn1X509ExtensionsEncodeEx(
|
|
IN DWORD dwCertEncodingType,
|
|
IN LPCSTR lpszStructType,
|
|
IN PCERT_EXTENSIONS pInfo,
|
|
IN DWORD dwFlags,
|
|
IN OPTIONAL PCRYPT_ENCODE_PARA pEncodePara,
|
|
OUT OPTIONAL void *pvEncoded,
|
|
IN OUT DWORD *pcbEncoded
|
|
);
|
|
BOOL WINAPI Asn1X509ExtensionsDecodeEx(
|
|
IN DWORD dwCertEncodingType,
|
|
IN LPCSTR lpszStructType,
|
|
IN const BYTE *pbEncoded,
|
|
IN DWORD cbEncoded,
|
|
IN DWORD dwFlags,
|
|
IN OPTIONAL PCRYPT_DECODE_PARA pDecodePara,
|
|
OUT OPTIONAL void *pvStructInfo,
|
|
IN OUT DWORD *pcbStructInfo
|
|
);
|
|
|
|
|
|
//+-------------------------------------------------------------------------
|
|
// ASN1 ASN.1 Public Key Info Encode / Decode functions
|
|
//--------------------------------------------------------------------------
|
|
BOOL WINAPI Asn1X509PublicKeyInfoEncodeEx(
|
|
IN DWORD dwCertEncodingType,
|
|
IN LPCSTR lpszStructType,
|
|
IN PCERT_PUBLIC_KEY_INFO pInfo,
|
|
IN DWORD dwFlags,
|
|
IN OPTIONAL PCRYPT_ENCODE_PARA pEncodePara,
|
|
OUT OPTIONAL void *pvEncoded,
|
|
IN OUT DWORD *pcbEncoded
|
|
);
|
|
BOOL WINAPI Asn1X509PublicKeyInfoDecodeEx(
|
|
IN DWORD dwCertEncodingType,
|
|
IN LPCSTR lpszStructType,
|
|
IN const BYTE *pbEncoded,
|
|
IN DWORD cbEncoded,
|
|
IN DWORD dwFlags,
|
|
IN OPTIONAL PCRYPT_DECODE_PARA pDecodePara,
|
|
OUT OPTIONAL void *pvStructInfo,
|
|
IN OUT DWORD *pcbStructInfo
|
|
);
|
|
|
|
//+-------------------------------------------------------------------------
|
|
// ASN1 ASN.1 PKCS#1 RSAPublicKey Encode / Decode functions
|
|
//--------------------------------------------------------------------------
|
|
BOOL WINAPI Asn1RSAPublicKeyStrucEncodeEx(
|
|
IN DWORD dwCertEncodingType,
|
|
IN LPCSTR lpszStructType,
|
|
IN PUBLICKEYSTRUC *pPubKeyStruc,
|
|
IN DWORD dwFlags,
|
|
IN OPTIONAL PCRYPT_ENCODE_PARA pEncodePara,
|
|
OUT OPTIONAL void *pvEncoded,
|
|
IN OUT DWORD *pcbEncoded
|
|
);
|
|
BOOL WINAPI Asn1RSAPublicKeyStrucDecodeEx(
|
|
IN DWORD dwCertEncodingType,
|
|
IN LPCSTR lpszStructType,
|
|
IN const BYTE *pbEncoded,
|
|
IN DWORD cbEncoded,
|
|
IN DWORD dwFlags,
|
|
IN OPTIONAL PCRYPT_DECODE_PARA pDecodePara,
|
|
OUT OPTIONAL void *pvStructInfo,
|
|
IN OUT DWORD *pcbStructInfo
|
|
);
|
|
|
|
//+-------------------------------------------------------------------------
|
|
// ASN1 X509 v3 Extension ASN.1 Encode / Decode functions
|
|
//--------------------------------------------------------------------------
|
|
BOOL WINAPI Asn1X509AuthorityKeyIdEncodeEx(
|
|
IN DWORD dwCertEncodingType,
|
|
IN LPCSTR lpszStructType,
|
|
IN PCERT_AUTHORITY_KEY_ID_INFO pInfo,
|
|
IN DWORD dwFlags,
|
|
IN OPTIONAL PCRYPT_ENCODE_PARA pEncodePara,
|
|
OUT OPTIONAL void *pvEncoded,
|
|
IN OUT DWORD *pcbEncoded
|
|
);
|
|
BOOL WINAPI Asn1X509AuthorityKeyIdDecodeEx(
|
|
IN DWORD dwCertEncodingType,
|
|
IN LPCSTR lpszStructType,
|
|
IN const BYTE *pbEncoded,
|
|
IN DWORD cbEncoded,
|
|
IN DWORD dwFlags,
|
|
IN OPTIONAL PCRYPT_DECODE_PARA pDecodePara,
|
|
OUT OPTIONAL void *pvStructInfo,
|
|
IN OUT DWORD *pcbStructInfo
|
|
);
|
|
BOOL WINAPI Asn1X509AuthorityKeyId2EncodeEx(
|
|
IN DWORD dwCertEncodingType,
|
|
IN LPCSTR lpszStructType,
|
|
IN PCERT_AUTHORITY_KEY_ID2_INFO pInfo,
|
|
IN DWORD dwFlags,
|
|
IN OPTIONAL PCRYPT_ENCODE_PARA pEncodePara,
|
|
OUT OPTIONAL void *pvEncoded,
|
|
IN OUT DWORD *pcbEncoded
|
|
);
|
|
BOOL WINAPI Asn1X509AuthorityKeyId2DecodeEx(
|
|
IN DWORD dwCertEncodingType,
|
|
IN LPCSTR lpszStructType,
|
|
IN const BYTE *pbEncoded,
|
|
IN DWORD cbEncoded,
|
|
IN DWORD dwFlags,
|
|
IN OPTIONAL PCRYPT_DECODE_PARA pDecodePara,
|
|
OUT OPTIONAL void *pvStructInfo,
|
|
IN OUT DWORD *pcbStructInfo
|
|
);
|
|
BOOL WINAPI Asn1X509KeyAttributesEncodeEx(
|
|
IN DWORD dwCertEncodingType,
|
|
IN LPCSTR lpszStructType,
|
|
IN PCERT_KEY_ATTRIBUTES_INFO pInfo,
|
|
IN DWORD dwFlags,
|
|
IN OPTIONAL PCRYPT_ENCODE_PARA pEncodePara,
|
|
OUT OPTIONAL void *pvEncoded,
|
|
IN OUT DWORD *pcbEncoded
|
|
);
|
|
BOOL WINAPI Asn1X509KeyAttributesDecodeEx(
|
|
IN DWORD dwCertEncodingType,
|
|
IN LPCSTR lpszStructType,
|
|
IN const BYTE *pbEncoded,
|
|
IN DWORD cbEncoded,
|
|
IN DWORD dwFlags,
|
|
IN OPTIONAL PCRYPT_DECODE_PARA pDecodePara,
|
|
OUT OPTIONAL void *pvStructInfo,
|
|
IN OUT DWORD *pcbStructInfo
|
|
);
|
|
BOOL WINAPI Asn1X509AltNameEncodeEx(
|
|
IN DWORD dwCertEncodingType,
|
|
IN LPCSTR lpszStructType,
|
|
IN PCERT_ALT_NAME_INFO pInfo,
|
|
IN DWORD dwFlags,
|
|
IN OPTIONAL PCRYPT_ENCODE_PARA pEncodePara,
|
|
OUT OPTIONAL void *pvEncoded,
|
|
IN OUT DWORD *pcbEncoded
|
|
);
|
|
BOOL WINAPI Asn1X509AltNameDecodeEx(
|
|
IN DWORD dwCertEncodingType,
|
|
IN LPCSTR lpszStructType,
|
|
IN const BYTE *pbEncoded,
|
|
IN DWORD cbEncoded,
|
|
IN DWORD dwFlags,
|
|
IN OPTIONAL PCRYPT_DECODE_PARA pDecodePara,
|
|
OUT OPTIONAL void *pvStructInfo,
|
|
IN OUT DWORD *pcbStructInfo
|
|
);
|
|
BOOL WINAPI Asn1X509KeyUsageRestrictionEncodeEx(
|
|
IN DWORD dwCertEncodingType,
|
|
IN LPCSTR lpszStructType,
|
|
IN PCERT_KEY_USAGE_RESTRICTION_INFO pInfo,
|
|
IN DWORD dwFlags,
|
|
IN OPTIONAL PCRYPT_ENCODE_PARA pEncodePara,
|
|
OUT OPTIONAL void *pvEncoded,
|
|
IN OUT DWORD *pcbEncoded
|
|
);
|
|
BOOL WINAPI Asn1X509KeyUsageRestrictionDecodeEx(
|
|
IN DWORD dwCertEncodingType,
|
|
IN LPCSTR lpszStructType,
|
|
IN const BYTE *pbEncoded,
|
|
IN DWORD cbEncoded,
|
|
IN DWORD dwFlags,
|
|
IN OPTIONAL PCRYPT_DECODE_PARA pDecodePara,
|
|
OUT OPTIONAL void *pvStructInfo,
|
|
IN OUT DWORD *pcbStructInfo
|
|
);
|
|
BOOL WINAPI Asn1X509BasicConstraintsEncodeEx(
|
|
IN DWORD dwCertEncodingType,
|
|
IN LPCSTR lpszStructType,
|
|
IN PCERT_BASIC_CONSTRAINTS_INFO pInfo,
|
|
IN DWORD dwFlags,
|
|
IN OPTIONAL PCRYPT_ENCODE_PARA pEncodePara,
|
|
OUT OPTIONAL void *pvEncoded,
|
|
IN OUT DWORD *pcbEncoded
|
|
);
|
|
BOOL WINAPI Asn1X509BasicConstraintsDecodeEx(
|
|
IN DWORD dwCertEncodingType,
|
|
IN LPCSTR lpszStructType,
|
|
IN const BYTE *pbEncoded,
|
|
IN DWORD cbEncoded,
|
|
IN DWORD dwFlags,
|
|
IN OPTIONAL PCRYPT_DECODE_PARA pDecodePara,
|
|
OUT OPTIONAL void *pvStructInfo,
|
|
IN OUT DWORD *pcbStructInfo
|
|
);
|
|
BOOL WINAPI Asn1X509BasicConstraints2EncodeEx(
|
|
IN DWORD dwCertEncodingType,
|
|
IN LPCSTR lpszStructType,
|
|
IN PCERT_BASIC_CONSTRAINTS2_INFO pInfo,
|
|
IN DWORD dwFlags,
|
|
IN OPTIONAL PCRYPT_ENCODE_PARA pEncodePara,
|
|
OUT OPTIONAL void *pvEncoded,
|
|
IN OUT DWORD *pcbEncoded
|
|
);
|
|
BOOL WINAPI Asn1X509BasicConstraints2DecodeEx(
|
|
IN DWORD dwCertEncodingType,
|
|
IN LPCSTR lpszStructType,
|
|
IN const BYTE *pbEncoded,
|
|
IN DWORD cbEncoded,
|
|
IN DWORD dwFlags,
|
|
IN OPTIONAL PCRYPT_DECODE_PARA pDecodePara,
|
|
OUT OPTIONAL void *pvStructInfo,
|
|
IN OUT DWORD *pcbStructInfo
|
|
);
|
|
BOOL WINAPI Asn1X509BitsEncodeEx(
|
|
IN DWORD dwCertEncodingType,
|
|
IN LPCSTR lpszStructType,
|
|
IN PCRYPT_BIT_BLOB pInfo,
|
|
IN DWORD dwFlags,
|
|
IN OPTIONAL PCRYPT_ENCODE_PARA pEncodePara,
|
|
OUT OPTIONAL void *pvEncoded,
|
|
IN OUT DWORD *pcbEncoded
|
|
);
|
|
BOOL WINAPI Asn1X509BitsDecodeEx(
|
|
IN DWORD dwCertEncodingType,
|
|
IN LPCSTR lpszStructType,
|
|
IN const BYTE *pbEncoded,
|
|
IN DWORD cbEncoded,
|
|
IN DWORD dwFlags,
|
|
IN OPTIONAL PCRYPT_DECODE_PARA pDecodePara,
|
|
OUT OPTIONAL void *pvStructInfo,
|
|
IN OUT DWORD *pcbStructInfo
|
|
);
|
|
BOOL WINAPI Asn1X509BitsWithoutTrailingZeroesEncodeEx(
|
|
IN DWORD dwCertEncodingType,
|
|
IN LPCSTR lpszStructType,
|
|
IN PCRYPT_BIT_BLOB pInfo,
|
|
IN DWORD dwFlags,
|
|
IN OPTIONAL PCRYPT_ENCODE_PARA pEncodePara,
|
|
OUT OPTIONAL void *pvEncoded,
|
|
IN OUT DWORD *pcbEncoded
|
|
);
|
|
BOOL WINAPI Asn1X509CertPoliciesEncodeEx(
|
|
IN DWORD dwCertEncodingType,
|
|
IN LPCSTR lpszStructType,
|
|
IN PCERT_POLICIES_INFO pInfo,
|
|
IN DWORD dwFlags,
|
|
IN OPTIONAL PCRYPT_ENCODE_PARA pEncodePara,
|
|
OUT OPTIONAL void *pvEncoded,
|
|
IN OUT DWORD *pcbEncoded
|
|
);
|
|
BOOL WINAPI Asn1X509CertPoliciesDecodeEx(
|
|
IN DWORD dwCertEncodingType,
|
|
IN LPCSTR lpszStructType,
|
|
IN const BYTE *pbEncoded,
|
|
IN DWORD cbEncoded,
|
|
IN DWORD dwFlags,
|
|
IN OPTIONAL PCRYPT_DECODE_PARA pDecodePara,
|
|
OUT OPTIONAL void *pvStructInfo,
|
|
IN OUT DWORD *pcbStructInfo
|
|
);
|
|
|
|
BOOL WINAPI Asn1X509CertPoliciesQualifier1DecodeEx(
|
|
IN DWORD dwCertEncodingType,
|
|
IN LPCSTR lpszStructType,
|
|
IN const BYTE *pbEncoded,
|
|
IN DWORD cbEncoded,
|
|
IN DWORD dwFlags,
|
|
IN OPTIONAL PCRYPT_DECODE_PARA pDecodePara,
|
|
OUT OPTIONAL void *pvStructInfo,
|
|
IN OUT DWORD *pcbStructInfo
|
|
);
|
|
|
|
|
|
BOOL WINAPI Asn1X509PKIXUserNoticeEncodeEx(
|
|
IN DWORD dwCertEncodingType,
|
|
IN LPCSTR lpszStructType,
|
|
IN PCERT_POLICY_QUALIFIER_USER_NOTICE pInfo,
|
|
IN DWORD dwFlags,
|
|
IN OPTIONAL PCRYPT_ENCODE_PARA pEncodePara,
|
|
OUT OPTIONAL void *pvEncoded,
|
|
IN OUT DWORD *pcbEncoded
|
|
);
|
|
|
|
BOOL WINAPI Asn1X509PKIXUserNoticeDecodeEx(
|
|
IN DWORD dwCertEncodingType,
|
|
IN LPCSTR lpszStructType,
|
|
IN const BYTE *pbEncoded,
|
|
IN DWORD cbEncoded,
|
|
IN DWORD dwFlags,
|
|
IN OPTIONAL PCRYPT_DECODE_PARA pDecodePara,
|
|
OUT OPTIONAL void *pvStructInfo,
|
|
IN OUT DWORD *pcbStructInfo
|
|
);
|
|
|
|
BOOL WINAPI Asn1X509AuthorityInfoAccessEncodeEx(
|
|
IN DWORD dwCertEncodingType,
|
|
IN LPCSTR lpszStructType,
|
|
IN PCERT_AUTHORITY_INFO_ACCESS pInfo,
|
|
IN DWORD dwFlags,
|
|
IN OPTIONAL PCRYPT_ENCODE_PARA pEncodePara,
|
|
OUT OPTIONAL void *pvEncoded,
|
|
IN OUT DWORD *pcbEncoded
|
|
);
|
|
BOOL WINAPI Asn1X509AuthorityInfoAccessDecodeEx(
|
|
IN DWORD dwCertEncodingType,
|
|
IN LPCSTR lpszStructType,
|
|
IN const BYTE *pbEncoded,
|
|
IN DWORD cbEncoded,
|
|
IN DWORD dwFlags,
|
|
IN OPTIONAL PCRYPT_DECODE_PARA pDecodePara,
|
|
OUT OPTIONAL void *pvStructInfo,
|
|
IN OUT DWORD *pcbStructInfo
|
|
);
|
|
BOOL WINAPI Asn1X509CrlDistPointsEncodeEx(
|
|
IN DWORD dwCertEncodingType,
|
|
IN LPCSTR lpszStructType,
|
|
IN PCRL_DIST_POINTS_INFO pInfo,
|
|
IN DWORD dwFlags,
|
|
IN OPTIONAL PCRYPT_ENCODE_PARA pEncodePara,
|
|
OUT OPTIONAL void *pvEncoded,
|
|
IN OUT DWORD *pcbEncoded
|
|
);
|
|
BOOL WINAPI Asn1X509CrlDistPointsDecodeEx(
|
|
IN DWORD dwCertEncodingType,
|
|
IN LPCSTR lpszStructType,
|
|
IN const BYTE *pbEncoded,
|
|
IN DWORD cbEncoded,
|
|
IN DWORD dwFlags,
|
|
IN OPTIONAL PCRYPT_DECODE_PARA pDecodePara,
|
|
OUT OPTIONAL void *pvStructInfo,
|
|
IN OUT DWORD *pcbStructInfo
|
|
);
|
|
|
|
BOOL WINAPI Asn1X509IntegerEncodeEx(
|
|
IN DWORD dwCertEncodingType,
|
|
IN LPCSTR lpszStructType,
|
|
IN int *pInfo,
|
|
IN DWORD dwFlags,
|
|
IN OPTIONAL PCRYPT_ENCODE_PARA pEncodePara,
|
|
OUT OPTIONAL void *pvEncoded,
|
|
IN OUT DWORD *pcbEncoded
|
|
);
|
|
BOOL WINAPI Asn1X509IntegerDecodeEx(
|
|
IN DWORD dwCertEncodingType,
|
|
IN LPCSTR lpszStructType,
|
|
IN const BYTE *pbEncoded,
|
|
IN DWORD cbEncoded,
|
|
IN DWORD dwFlags,
|
|
IN OPTIONAL PCRYPT_DECODE_PARA pDecodePara,
|
|
OUT OPTIONAL void *pvStructInfo,
|
|
IN OUT DWORD *pcbStructInfo
|
|
);
|
|
BOOL WINAPI Asn1X509MultiByteIntegerEncodeEx(
|
|
IN DWORD dwCertEncodingType,
|
|
IN LPCSTR lpszStructType,
|
|
IN PCRYPT_INTEGER_BLOB pInfo,
|
|
IN DWORD dwFlags,
|
|
IN OPTIONAL PCRYPT_ENCODE_PARA pEncodePara,
|
|
OUT OPTIONAL void *pvEncoded,
|
|
IN OUT DWORD *pcbEncoded
|
|
);
|
|
BOOL WINAPI Asn1X509MultiByteIntegerDecodeEx(
|
|
IN DWORD dwCertEncodingType,
|
|
IN LPCSTR lpszStructType,
|
|
IN const BYTE *pbEncoded,
|
|
IN DWORD cbEncoded,
|
|
IN DWORD dwFlags,
|
|
IN OPTIONAL PCRYPT_DECODE_PARA pDecodePara,
|
|
OUT OPTIONAL void *pvStructInfo,
|
|
IN OUT DWORD *pcbStructInfo
|
|
);
|
|
BOOL WINAPI Asn1X509EnumeratedEncodeEx(
|
|
IN DWORD dwCertEncodingType,
|
|
IN LPCSTR lpszStructType,
|
|
IN int *pInfo,
|
|
IN DWORD dwFlags,
|
|
IN OPTIONAL PCRYPT_ENCODE_PARA pEncodePara,
|
|
OUT OPTIONAL void *pvEncoded,
|
|
IN OUT DWORD *pcbEncoded
|
|
);
|
|
BOOL WINAPI Asn1X509EnumeratedDecodeEx(
|
|
IN DWORD dwCertEncodingType,
|
|
IN LPCSTR lpszStructType,
|
|
IN const BYTE *pbEncoded,
|
|
IN DWORD cbEncoded,
|
|
IN DWORD dwFlags,
|
|
IN OPTIONAL PCRYPT_DECODE_PARA pDecodePara,
|
|
OUT OPTIONAL void *pvStructInfo,
|
|
IN OUT DWORD *pcbStructInfo
|
|
);
|
|
BOOL WINAPI Asn1X509OctetStringEncodeEx(
|
|
IN DWORD dwCertEncodingType,
|
|
IN LPCSTR lpszStructType,
|
|
IN PCRYPT_DATA_BLOB pInfo,
|
|
IN DWORD dwFlags,
|
|
IN OPTIONAL PCRYPT_ENCODE_PARA pEncodePara,
|
|
OUT OPTIONAL void *pvEncoded,
|
|
IN OUT DWORD *pcbEncoded
|
|
);
|
|
BOOL WINAPI Asn1X509OctetStringDecodeEx(
|
|
IN DWORD dwCertEncodingType,
|
|
IN LPCSTR lpszStructType,
|
|
IN const BYTE *pbEncoded,
|
|
IN DWORD cbEncoded,
|
|
IN DWORD dwFlags,
|
|
IN OPTIONAL PCRYPT_DECODE_PARA pDecodePara,
|
|
OUT OPTIONAL void *pvStructInfo,
|
|
IN OUT DWORD *pcbStructInfo
|
|
);
|
|
BOOL WINAPI Asn1X509ChoiceOfTimeEncodeEx(
|
|
IN DWORD dwCertEncodingType,
|
|
IN LPCSTR lpszStructType,
|
|
IN LPFILETIME pInfo,
|
|
IN DWORD dwFlags,
|
|
IN OPTIONAL PCRYPT_ENCODE_PARA pEncodePara,
|
|
OUT OPTIONAL void *pvEncoded,
|
|
IN OUT DWORD *pcbEncoded
|
|
);
|
|
BOOL WINAPI Asn1X509ChoiceOfTimeDecodeEx(
|
|
IN DWORD dwCertEncodingType,
|
|
IN LPCSTR lpszStructType,
|
|
IN const BYTE *pbEncoded,
|
|
IN DWORD cbEncoded,
|
|
IN DWORD dwFlags,
|
|
IN OPTIONAL PCRYPT_DECODE_PARA pDecodePara,
|
|
OUT OPTIONAL void *pvStructInfo,
|
|
IN OUT DWORD *pcbStructInfo
|
|
);
|
|
BOOL WINAPI Asn1X509AttributeEncodeEx(
|
|
IN DWORD dwCertEncodingType,
|
|
IN LPCSTR lpszStructType,
|
|
IN PCRYPT_ATTRIBUTE pInfo,
|
|
IN DWORD dwFlags,
|
|
IN OPTIONAL PCRYPT_ENCODE_PARA pEncodePara,
|
|
OUT OPTIONAL void *pvEncoded,
|
|
IN OUT DWORD *pcbEncoded
|
|
);
|
|
BOOL WINAPI Asn1X509AttributeDecodeEx(
|
|
IN DWORD dwCertEncodingType,
|
|
IN LPCSTR lpszStructType,
|
|
IN const BYTE *pbEncoded,
|
|
IN DWORD cbEncoded,
|
|
IN DWORD dwFlags,
|
|
IN OPTIONAL PCRYPT_DECODE_PARA pDecodePara,
|
|
OUT OPTIONAL void *pvStructInfo,
|
|
IN OUT DWORD *pcbStructInfo
|
|
);
|
|
BOOL WINAPI Asn1X509ContentInfoSequenceOfAnyEncodeEx(
|
|
IN DWORD dwCertEncodingType,
|
|
IN LPCSTR lpszStructType,
|
|
IN PCRYPT_CONTENT_INFO_SEQUENCE_OF_ANY pInfo,
|
|
IN DWORD dwFlags,
|
|
IN OPTIONAL PCRYPT_ENCODE_PARA pEncodePara,
|
|
OUT OPTIONAL void *pvEncoded,
|
|
IN OUT DWORD *pcbEncoded
|
|
);
|
|
BOOL WINAPI Asn1X509ContentInfoSequenceOfAnyDecodeEx(
|
|
IN DWORD dwCertEncodingType,
|
|
IN LPCSTR lpszStructType,
|
|
IN const BYTE *pbEncoded,
|
|
IN DWORD cbEncoded,
|
|
IN DWORD dwFlags,
|
|
IN OPTIONAL PCRYPT_DECODE_PARA pDecodePara,
|
|
OUT OPTIONAL void *pvStructInfo,
|
|
IN OUT DWORD *pcbStructInfo
|
|
);
|
|
BOOL WINAPI Asn1X509ContentInfoEncodeEx(
|
|
IN DWORD dwCertEncodingType,
|
|
IN LPCSTR lpszStructType,
|
|
IN PCRYPT_CONTENT_INFO pInfo,
|
|
IN DWORD dwFlags,
|
|
IN OPTIONAL PCRYPT_ENCODE_PARA pEncodePara,
|
|
OUT OPTIONAL void *pvEncoded,
|
|
IN OUT DWORD *pcbEncoded
|
|
);
|
|
BOOL WINAPI Asn1X509ContentInfoDecodeEx(
|
|
IN DWORD dwCertEncodingType,
|
|
IN LPCSTR lpszStructType,
|
|
IN const BYTE *pbEncoded,
|
|
IN DWORD cbEncoded,
|
|
IN DWORD dwFlags,
|
|
IN OPTIONAL PCRYPT_DECODE_PARA pDecodePara,
|
|
OUT OPTIONAL void *pvStructInfo,
|
|
IN OUT DWORD *pcbStructInfo
|
|
);
|
|
BOOL WINAPI Asn1X509SequenceOfAnyEncodeEx(
|
|
IN DWORD dwCertEncodingType,
|
|
IN LPCSTR lpszStructType,
|
|
IN PCRYPT_SEQUENCE_OF_ANY pInfo,
|
|
IN DWORD dwFlags,
|
|
IN OPTIONAL PCRYPT_ENCODE_PARA pEncodePara,
|
|
OUT OPTIONAL void *pvEncoded,
|
|
IN OUT DWORD *pcbEncoded
|
|
);
|
|
BOOL WINAPI Asn1X509SequenceOfAnyDecodeEx(
|
|
IN DWORD dwCertEncodingType,
|
|
IN LPCSTR lpszStructType,
|
|
IN const BYTE *pbEncoded,
|
|
IN DWORD cbEncoded,
|
|
IN DWORD dwFlags,
|
|
IN OPTIONAL PCRYPT_DECODE_PARA pDecodePara,
|
|
OUT OPTIONAL void *pvStructInfo,
|
|
IN OUT DWORD *pcbStructInfo
|
|
);
|
|
|
|
BOOL WINAPI Asn1X509MultiByteUINTEncodeEx(
|
|
IN DWORD dwCertEncodingType,
|
|
IN LPCSTR lpszStructType,
|
|
IN PCRYPT_UINT_BLOB pInfo,
|
|
IN DWORD dwFlags,
|
|
IN OPTIONAL PCRYPT_ENCODE_PARA pEncodePara,
|
|
OUT OPTIONAL void *pvEncoded,
|
|
IN OUT DWORD *pcbEncoded
|
|
);
|
|
BOOL WINAPI Asn1X509MultiByteUINTDecodeEx(
|
|
IN DWORD dwCertEncodingType,
|
|
IN LPCSTR lpszStructType,
|
|
IN const BYTE *pbEncoded,
|
|
IN DWORD cbEncoded,
|
|
IN DWORD dwFlags,
|
|
IN OPTIONAL PCRYPT_DECODE_PARA pDecodePara,
|
|
OUT OPTIONAL void *pvStructInfo,
|
|
IN OUT DWORD *pcbStructInfo
|
|
);
|
|
BOOL WINAPI Asn1X509DSSParametersEncodeEx(
|
|
IN DWORD dwCertEncodingType,
|
|
IN LPCSTR lpszStructType,
|
|
IN PCERT_DSS_PARAMETERS pInfo,
|
|
IN DWORD dwFlags,
|
|
IN OPTIONAL PCRYPT_ENCODE_PARA pEncodePara,
|
|
OUT OPTIONAL void *pvEncoded,
|
|
IN OUT DWORD *pcbEncoded
|
|
);
|
|
BOOL WINAPI Asn1X509DSSParametersDecodeEx(
|
|
IN DWORD dwCertEncodingType,
|
|
IN LPCSTR lpszStructType,
|
|
IN const BYTE *pbEncoded,
|
|
IN DWORD cbEncoded,
|
|
IN DWORD dwFlags,
|
|
IN OPTIONAL PCRYPT_DECODE_PARA pDecodePara,
|
|
OUT OPTIONAL void *pvStructInfo,
|
|
IN OUT DWORD *pcbStructInfo
|
|
);
|
|
BOOL WINAPI Asn1X509DSSSignatureEncodeEx(
|
|
IN DWORD dwCertEncodingType,
|
|
IN LPCSTR lpszStructType,
|
|
IN BYTE rgbSignature[CERT_DSS_SIGNATURE_LEN],
|
|
IN DWORD dwFlags,
|
|
IN OPTIONAL PCRYPT_ENCODE_PARA pEncodePara,
|
|
OUT OPTIONAL void *pvEncoded,
|
|
IN OUT DWORD *pcbEncoded
|
|
);
|
|
BOOL WINAPI Asn1X509DSSSignatureDecodeEx(
|
|
IN DWORD dwCertEncodingType,
|
|
IN LPCSTR lpszStructType,
|
|
IN const BYTE *pbEncoded,
|
|
IN DWORD cbEncoded,
|
|
IN DWORD dwFlags,
|
|
IN OPTIONAL PCRYPT_DECODE_PARA pDecodePara,
|
|
OUT OPTIONAL void *pvStructInfo,
|
|
IN OUT DWORD *pcbStructInfo
|
|
);
|
|
|
|
BOOL WINAPI Asn1X509DHParametersEncodeEx(
|
|
IN DWORD dwCertEncodingType,
|
|
IN LPCSTR lpszStructType,
|
|
IN PCERT_DH_PARAMETERS pInfo,
|
|
IN DWORD dwFlags,
|
|
IN OPTIONAL PCRYPT_ENCODE_PARA pEncodePara,
|
|
OUT OPTIONAL void *pvEncoded,
|
|
IN OUT DWORD *pcbEncoded
|
|
);
|
|
BOOL WINAPI Asn1X509DHParametersDecodeEx(
|
|
IN DWORD dwCertEncodingType,
|
|
IN LPCSTR lpszStructType,
|
|
IN const BYTE *pbEncoded,
|
|
IN DWORD cbEncoded,
|
|
IN DWORD dwFlags,
|
|
IN OPTIONAL PCRYPT_DECODE_PARA pDecodePara,
|
|
OUT OPTIONAL void *pvStructInfo,
|
|
IN OUT DWORD *pcbStructInfo
|
|
);
|
|
|
|
BOOL WINAPI Asn1X942DhParametersEncodeEx(
|
|
IN DWORD dwCertEncodingType,
|
|
IN LPCSTR lpszStructType,
|
|
IN PCERT_X942_DH_PARAMETERS pInfo,
|
|
IN DWORD dwFlags,
|
|
IN OPTIONAL PCRYPT_ENCODE_PARA pEncodePara,
|
|
OUT OPTIONAL void *pvEncoded,
|
|
IN OUT DWORD *pcbEncoded
|
|
);
|
|
BOOL WINAPI Asn1X942DhParametersDecodeEx(
|
|
IN DWORD dwCertEncodingType,
|
|
IN LPCSTR lpszStructType,
|
|
IN const BYTE *pbEncoded,
|
|
IN DWORD cbEncoded,
|
|
IN DWORD dwFlags,
|
|
IN OPTIONAL PCRYPT_DECODE_PARA pDecodePara,
|
|
OUT OPTIONAL void *pvStructInfo,
|
|
IN OUT DWORD *pcbStructInfo
|
|
);
|
|
|
|
BOOL WINAPI Asn1X942OtherInfoEncodeEx(
|
|
IN DWORD dwCertEncodingType,
|
|
IN LPCSTR lpszStructType,
|
|
IN PCRYPT_X942_OTHER_INFO pInfo,
|
|
IN DWORD dwFlags,
|
|
IN OPTIONAL PCRYPT_ENCODE_PARA pEncodePara,
|
|
OUT OPTIONAL void *pvEncoded,
|
|
IN OUT DWORD *pcbEncoded
|
|
);
|
|
BOOL WINAPI Asn1X942OtherInfoDecodeEx(
|
|
IN DWORD dwCertEncodingType,
|
|
IN LPCSTR lpszStructType,
|
|
IN const BYTE *pbEncoded,
|
|
IN DWORD cbEncoded,
|
|
IN DWORD dwFlags,
|
|
IN OPTIONAL PCRYPT_DECODE_PARA pDecodePara,
|
|
OUT OPTIONAL void *pvStructInfo,
|
|
IN OUT DWORD *pcbStructInfo
|
|
);
|
|
|
|
BOOL WINAPI Asn1RC2CBCParametersEncodeEx(
|
|
IN DWORD dwCertEncodingType,
|
|
IN LPCSTR lpszStructType,
|
|
IN PCRYPT_RC2_CBC_PARAMETERS pInfo,
|
|
IN DWORD dwFlags,
|
|
IN OPTIONAL PCRYPT_ENCODE_PARA pEncodePara,
|
|
OUT OPTIONAL void *pvEncoded,
|
|
IN OUT DWORD *pcbEncoded
|
|
);
|
|
BOOL WINAPI Asn1RC2CBCParametersDecodeEx(
|
|
IN DWORD dwCertEncodingType,
|
|
IN LPCSTR lpszStructType,
|
|
IN const BYTE *pbEncoded,
|
|
IN DWORD cbEncoded,
|
|
IN DWORD dwFlags,
|
|
IN OPTIONAL PCRYPT_DECODE_PARA pDecodePara,
|
|
OUT OPTIONAL void *pvStructInfo,
|
|
IN OUT DWORD *pcbStructInfo
|
|
);
|
|
BOOL WINAPI Asn1SMIMECapabilitiesEncodeEx(
|
|
IN DWORD dwCertEncodingType,
|
|
IN LPCSTR lpszStructType,
|
|
IN PCRYPT_SMIME_CAPABILITIES pInfo,
|
|
IN DWORD dwFlags,
|
|
IN OPTIONAL PCRYPT_ENCODE_PARA pEncodePara,
|
|
OUT OPTIONAL void *pvEncoded,
|
|
IN OUT DWORD *pcbEncoded
|
|
);
|
|
BOOL WINAPI Asn1SMIMECapabilitiesDecodeEx(
|
|
IN DWORD dwCertEncodingType,
|
|
IN LPCSTR lpszStructType,
|
|
IN const BYTE *pbEncoded,
|
|
IN DWORD cbEncoded,
|
|
IN DWORD dwFlags,
|
|
IN OPTIONAL PCRYPT_DECODE_PARA pDecodePara,
|
|
OUT OPTIONAL void *pvStructInfo,
|
|
IN OUT DWORD *pcbStructInfo
|
|
);
|
|
|
|
BOOL WINAPI Asn1UtcTimeEncodeEx(
|
|
IN DWORD dwCertEncodingType,
|
|
IN LPCSTR lpszStructType,
|
|
IN FILETIME * pFileTime,
|
|
IN DWORD dwFlags,
|
|
IN OPTIONAL PCRYPT_ENCODE_PARA pEncodePara,
|
|
OUT OPTIONAL void *pvEncoded,
|
|
IN OUT DWORD *pcbEncoded
|
|
);
|
|
BOOL WINAPI Asn1UtcTimeDecodeEx(
|
|
IN DWORD dwCertEncodingType,
|
|
IN LPCSTR lpszStructType,
|
|
IN const BYTE *pbEncoded,
|
|
IN DWORD cbEncoded,
|
|
IN DWORD dwFlags,
|
|
IN OPTIONAL PCRYPT_DECODE_PARA pDecodePara,
|
|
OUT OPTIONAL void *pvStructInfo,
|
|
IN OUT DWORD *pcbStructInfo
|
|
);
|
|
|
|
BOOL WINAPI Asn1TimeStampRequestInfoEncodeEx(
|
|
IN DWORD dwCertEncodingType,
|
|
IN LPCSTR lpszStructType,
|
|
IN PCRYPT_TIME_STAMP_REQUEST_INFO pInfo,
|
|
IN DWORD dwFlags,
|
|
IN OPTIONAL PCRYPT_ENCODE_PARA pEncodePara,
|
|
OUT OPTIONAL void *pvEncoded,
|
|
IN OUT DWORD *pcbEncoded
|
|
);
|
|
|
|
BOOL WINAPI Asn1TimeStampRequestInfoDecodeEx(
|
|
IN DWORD dwCertEncodingType,
|
|
IN LPCSTR lpszStructType,
|
|
IN const BYTE *pbEncoded,
|
|
IN DWORD cbEncoded,
|
|
IN DWORD dwFlags,
|
|
IN OPTIONAL PCRYPT_DECODE_PARA pDecodePara,
|
|
OUT OPTIONAL void *pvStructInfo,
|
|
IN OUT DWORD *pcbStructInfo
|
|
);
|
|
|
|
BOOL WINAPI Asn1X509AttributesEncodeEx(
|
|
IN DWORD dwCertEncodingType,
|
|
IN LPCSTR lpszStructType,
|
|
IN PCRYPT_ATTRIBUTES pInfo,
|
|
IN DWORD dwFlags,
|
|
IN OPTIONAL PCRYPT_ENCODE_PARA pEncodePara,
|
|
OUT OPTIONAL void *pvEncoded,
|
|
IN OUT DWORD *pcbEncoded
|
|
);
|
|
BOOL WINAPI Asn1X509AttributesDecodeEx(
|
|
IN DWORD dwCertEncodingType,
|
|
IN LPCSTR lpszStructType,
|
|
IN const BYTE *pbEncoded,
|
|
IN DWORD cbEncoded,
|
|
IN DWORD dwFlags,
|
|
IN OPTIONAL PCRYPT_DECODE_PARA pDecodePara,
|
|
OUT OPTIONAL void *pvStructInfo,
|
|
IN OUT DWORD *pcbStructInfo
|
|
);
|
|
|
|
//+-------------------------------------------------------------------------
|
|
// ASN1 X509 Certificate Trust List (CTL) ASN.1 Encode / Decode functions
|
|
//--------------------------------------------------------------------------
|
|
BOOL WINAPI Asn1X509CtlUsageEncodeEx(
|
|
IN DWORD dwCertEncodingType,
|
|
IN LPCSTR lpszStructType,
|
|
IN PCTL_USAGE pInfo,
|
|
IN DWORD dwFlags,
|
|
IN OPTIONAL PCRYPT_ENCODE_PARA pEncodePara,
|
|
OUT OPTIONAL void *pvEncoded,
|
|
IN OUT DWORD *pcbEncoded
|
|
);
|
|
BOOL WINAPI Asn1X509CtlUsageDecodeEx(
|
|
IN DWORD dwCertEncodingType,
|
|
IN LPCSTR lpszStructType,
|
|
IN const BYTE *pbEncoded,
|
|
IN DWORD cbEncoded,
|
|
IN DWORD dwFlags,
|
|
IN OPTIONAL PCRYPT_DECODE_PARA pDecodePara,
|
|
OUT OPTIONAL void *pvStructInfo,
|
|
IN OUT DWORD *pcbStructInfo
|
|
);
|
|
BOOL WINAPI Asn1X509CtlInfoEncodeEx(
|
|
IN DWORD dwCertEncodingType,
|
|
IN LPCSTR lpszStructType,
|
|
IN PCTL_INFO pInfo,
|
|
IN DWORD dwFlags,
|
|
IN OPTIONAL PCRYPT_ENCODE_PARA pEncodePara,
|
|
OUT OPTIONAL void *pvEncoded,
|
|
IN OUT DWORD *pcbEncoded
|
|
);
|
|
BOOL WINAPI Asn1X509CtlInfoDecodeEx(
|
|
IN DWORD dwCertEncodingType,
|
|
IN LPCSTR lpszStructType,
|
|
IN const BYTE *pbEncoded,
|
|
IN DWORD cbEncoded,
|
|
IN DWORD dwFlags,
|
|
IN OPTIONAL PCRYPT_DECODE_PARA pDecodePara,
|
|
OUT OPTIONAL void *pvStructInfo,
|
|
IN OUT DWORD *pcbStructInfo
|
|
);
|
|
|
|
BOOL WINAPI Asn1X509CertPairEncodeEx(
|
|
IN DWORD dwCertEncodingType,
|
|
IN LPCSTR lpszStructType,
|
|
IN PCERT_PAIR pInfo,
|
|
IN DWORD dwFlags,
|
|
IN OPTIONAL PCRYPT_ENCODE_PARA pEncodePara,
|
|
OUT OPTIONAL void *pvEncoded,
|
|
IN OUT DWORD *pcbEncoded
|
|
);
|
|
BOOL WINAPI Asn1X509CertPairDecodeEx(
|
|
IN DWORD dwCertEncodingType,
|
|
IN LPCSTR lpszStructType,
|
|
IN const BYTE *pbEncoded,
|
|
IN DWORD cbEncoded,
|
|
IN DWORD dwFlags,
|
|
IN OPTIONAL PCRYPT_DECODE_PARA pDecodePara,
|
|
OUT OPTIONAL void *pvStructInfo,
|
|
IN OUT DWORD *pcbStructInfo
|
|
);
|
|
|
|
BOOL WINAPI Asn1X509NameConstraintsEncodeEx(
|
|
IN DWORD dwCertEncodingType,
|
|
IN LPCSTR lpszStructType,
|
|
IN PCERT_NAME_CONSTRAINTS_INFO pInfo,
|
|
IN DWORD dwFlags,
|
|
IN OPTIONAL PCRYPT_ENCODE_PARA pEncodePara,
|
|
OUT OPTIONAL void *pvEncoded,
|
|
IN OUT DWORD *pcbEncoded
|
|
);
|
|
BOOL WINAPI Asn1X509NameConstraintsDecodeEx(
|
|
IN DWORD dwCertEncodingType,
|
|
IN LPCSTR lpszStructType,
|
|
IN const BYTE *pbEncoded,
|
|
IN DWORD cbEncoded,
|
|
IN DWORD dwFlags,
|
|
IN OPTIONAL PCRYPT_DECODE_PARA pDecodePara,
|
|
OUT OPTIONAL void *pvStructInfo,
|
|
IN OUT DWORD *pcbStructInfo
|
|
);
|
|
|
|
BOOL WINAPI Asn1X509CrlIssuingDistPointEncodeEx(
|
|
IN DWORD dwCertEncodingType,
|
|
IN LPCSTR lpszStructType,
|
|
IN PCRL_ISSUING_DIST_POINT pInfo,
|
|
IN DWORD dwFlags,
|
|
IN OPTIONAL PCRYPT_ENCODE_PARA pEncodePara,
|
|
OUT OPTIONAL void *pvEncoded,
|
|
IN OUT DWORD *pcbEncoded
|
|
);
|
|
BOOL WINAPI Asn1X509CrlIssuingDistPointDecodeEx(
|
|
IN DWORD dwCertEncodingType,
|
|
IN LPCSTR lpszStructType,
|
|
IN const BYTE *pbEncoded,
|
|
IN DWORD cbEncoded,
|
|
IN DWORD dwFlags,
|
|
IN OPTIONAL PCRYPT_DECODE_PARA pDecodePara,
|
|
OUT OPTIONAL void *pvStructInfo,
|
|
IN OUT DWORD *pcbStructInfo
|
|
);
|
|
|
|
BOOL WINAPI Asn1X509PolicyMappingsEncodeEx(
|
|
IN DWORD dwCertEncodingType,
|
|
IN LPCSTR lpszStructType,
|
|
IN PCERT_POLICY_MAPPINGS_INFO pInfo,
|
|
IN DWORD dwFlags,
|
|
IN OPTIONAL PCRYPT_ENCODE_PARA pEncodePara,
|
|
OUT OPTIONAL void *pvEncoded,
|
|
IN OUT DWORD *pcbEncoded
|
|
);
|
|
BOOL WINAPI Asn1X509PolicyMappingsDecodeEx(
|
|
IN DWORD dwCertEncodingType,
|
|
IN LPCSTR lpszStructType,
|
|
IN const BYTE *pbEncoded,
|
|
IN DWORD cbEncoded,
|
|
IN DWORD dwFlags,
|
|
IN OPTIONAL PCRYPT_DECODE_PARA pDecodePara,
|
|
OUT OPTIONAL void *pvStructInfo,
|
|
IN OUT DWORD *pcbStructInfo
|
|
);
|
|
|
|
BOOL WINAPI Asn1X509PolicyConstraintsEncodeEx(
|
|
IN DWORD dwCertEncodingType,
|
|
IN LPCSTR lpszStructType,
|
|
IN PCERT_POLICY_CONSTRAINTS_INFO pInfo,
|
|
IN DWORD dwFlags,
|
|
IN OPTIONAL PCRYPT_ENCODE_PARA pEncodePara,
|
|
OUT OPTIONAL void *pvEncoded,
|
|
IN OUT DWORD *pcbEncoded
|
|
);
|
|
BOOL WINAPI Asn1X509PolicyConstraintsDecodeEx(
|
|
IN DWORD dwCertEncodingType,
|
|
IN LPCSTR lpszStructType,
|
|
IN const BYTE *pbEncoded,
|
|
IN DWORD cbEncoded,
|
|
IN DWORD dwFlags,
|
|
IN OPTIONAL PCRYPT_DECODE_PARA pDecodePara,
|
|
OUT OPTIONAL void *pvStructInfo,
|
|
IN OUT DWORD *pcbStructInfo
|
|
);
|
|
|
|
BOOL WINAPI Asn1X509CrossCertDistPointsEncodeEx(
|
|
IN DWORD dwCertEncodingType,
|
|
IN LPCSTR lpszStructType,
|
|
IN PCROSS_CERT_DIST_POINTS_INFO pInfo,
|
|
IN DWORD dwFlags,
|
|
IN OPTIONAL PCRYPT_ENCODE_PARA pEncodePara,
|
|
OUT OPTIONAL void *pvEncoded,
|
|
IN OUT DWORD *pcbEncoded
|
|
);
|
|
BOOL WINAPI Asn1X509CrossCertDistPointsDecodeEx(
|
|
IN DWORD dwCertEncodingType,
|
|
IN LPCSTR lpszStructType,
|
|
IN const BYTE *pbEncoded,
|
|
IN DWORD cbEncoded,
|
|
IN DWORD dwFlags,
|
|
IN OPTIONAL PCRYPT_DECODE_PARA pDecodePara,
|
|
OUT OPTIONAL void *pvStructInfo,
|
|
IN OUT DWORD *pcbStructInfo
|
|
);
|
|
|
|
//+=========================================================================
|
|
// Certificate Management Messages over CMS (CMC) Encode/Decode Functions
|
|
//==========================================================================
|
|
BOOL WINAPI Asn1CmcDataEncodeEx(
|
|
IN DWORD dwCertEncodingType,
|
|
IN LPCSTR lpszStructType,
|
|
IN PCMC_DATA_INFO pInfo,
|
|
IN DWORD dwFlags,
|
|
IN OPTIONAL PCRYPT_ENCODE_PARA pEncodePara,
|
|
OUT OPTIONAL void *pvEncoded,
|
|
IN OUT DWORD *pcbEncoded
|
|
);
|
|
BOOL WINAPI Asn1CmcDataDecodeEx(
|
|
IN DWORD dwCertEncodingType,
|
|
IN LPCSTR lpszStructType,
|
|
IN const BYTE *pbEncoded,
|
|
IN DWORD cbEncoded,
|
|
IN DWORD dwFlags,
|
|
IN OPTIONAL PCRYPT_DECODE_PARA pDecodePara,
|
|
OUT OPTIONAL void *pvStructInfo,
|
|
IN OUT DWORD *pcbStructInfo
|
|
);
|
|
|
|
BOOL WINAPI Asn1CmcResponseEncodeEx(
|
|
IN DWORD dwCertEncodingType,
|
|
IN LPCSTR lpszStructType,
|
|
IN PCMC_RESPONSE_INFO pInfo,
|
|
IN DWORD dwFlags,
|
|
IN OPTIONAL PCRYPT_ENCODE_PARA pEncodePara,
|
|
OUT OPTIONAL void *pvEncoded,
|
|
IN OUT DWORD *pcbEncoded
|
|
);
|
|
BOOL WINAPI Asn1CmcResponseDecodeEx(
|
|
IN DWORD dwCertEncodingType,
|
|
IN LPCSTR lpszStructType,
|
|
IN const BYTE *pbEncoded,
|
|
IN DWORD cbEncoded,
|
|
IN DWORD dwFlags,
|
|
IN OPTIONAL PCRYPT_DECODE_PARA pDecodePara,
|
|
OUT OPTIONAL void *pvStructInfo,
|
|
IN OUT DWORD *pcbStructInfo
|
|
);
|
|
|
|
BOOL WINAPI Asn1CmcStatusEncodeEx(
|
|
IN DWORD dwCertEncodingType,
|
|
IN LPCSTR lpszStructType,
|
|
IN PCMC_STATUS_INFO pInfo,
|
|
IN DWORD dwFlags,
|
|
IN OPTIONAL PCRYPT_ENCODE_PARA pEncodePara,
|
|
OUT OPTIONAL void *pvEncoded,
|
|
IN OUT DWORD *pcbEncoded
|
|
);
|
|
BOOL WINAPI Asn1CmcStatusDecodeEx(
|
|
IN DWORD dwCertEncodingType,
|
|
IN LPCSTR lpszStructType,
|
|
IN const BYTE *pbEncoded,
|
|
IN DWORD cbEncoded,
|
|
IN DWORD dwFlags,
|
|
IN OPTIONAL PCRYPT_DECODE_PARA pDecodePara,
|
|
OUT OPTIONAL void *pvStructInfo,
|
|
IN OUT DWORD *pcbStructInfo
|
|
);
|
|
|
|
BOOL WINAPI Asn1CmcAddExtensionsEncodeEx(
|
|
IN DWORD dwCertEncodingType,
|
|
IN LPCSTR lpszStructType,
|
|
IN PCMC_ADD_EXTENSIONS_INFO pInfo,
|
|
IN DWORD dwFlags,
|
|
IN OPTIONAL PCRYPT_ENCODE_PARA pEncodePara,
|
|
OUT OPTIONAL void *pvEncoded,
|
|
IN OUT DWORD *pcbEncoded
|
|
);
|
|
BOOL WINAPI Asn1CmcAddExtensionsDecodeEx(
|
|
IN DWORD dwCertEncodingType,
|
|
IN LPCSTR lpszStructType,
|
|
IN const BYTE *pbEncoded,
|
|
IN DWORD cbEncoded,
|
|
IN DWORD dwFlags,
|
|
IN OPTIONAL PCRYPT_DECODE_PARA pDecodePara,
|
|
OUT OPTIONAL void *pvStructInfo,
|
|
IN OUT DWORD *pcbStructInfo
|
|
);
|
|
|
|
BOOL WINAPI Asn1CmcAddAttributesEncodeEx(
|
|
IN DWORD dwCertEncodingType,
|
|
IN LPCSTR lpszStructType,
|
|
IN PCMC_ADD_ATTRIBUTES_INFO pInfo,
|
|
IN DWORD dwFlags,
|
|
IN OPTIONAL PCRYPT_ENCODE_PARA pEncodePara,
|
|
OUT OPTIONAL void *pvEncoded,
|
|
IN OUT DWORD *pcbEncoded
|
|
);
|
|
BOOL WINAPI Asn1CmcAddAttributesDecodeEx(
|
|
IN DWORD dwCertEncodingType,
|
|
IN LPCSTR lpszStructType,
|
|
IN const BYTE *pbEncoded,
|
|
IN DWORD cbEncoded,
|
|
IN DWORD dwFlags,
|
|
IN OPTIONAL PCRYPT_DECODE_PARA pDecodePara,
|
|
OUT OPTIONAL void *pvStructInfo,
|
|
IN OUT DWORD *pcbStructInfo
|
|
);
|
|
|
|
//+=========================================================================
|
|
// Certificate Template Encode/Decode Functions
|
|
//==========================================================================
|
|
|
|
BOOL WINAPI Asn1X509CertTemplateEncodeEx(
|
|
IN DWORD dwCertEncodingType,
|
|
IN LPCSTR lpszStructType,
|
|
IN PCERT_TEMPLATE_EXT pInfo,
|
|
IN DWORD dwFlags,
|
|
IN OPTIONAL PCRYPT_ENCODE_PARA pEncodePara,
|
|
OUT OPTIONAL void *pvEncoded,
|
|
IN OUT DWORD *pcbEncoded
|
|
);
|
|
BOOL WINAPI Asn1X509CertTemplateDecodeEx(
|
|
IN DWORD dwCertEncodingType,
|
|
IN LPCSTR lpszStructType,
|
|
IN const BYTE *pbEncoded,
|
|
IN DWORD cbEncoded,
|
|
IN DWORD dwFlags,
|
|
IN OPTIONAL PCRYPT_DECODE_PARA pDecodePara,
|
|
OUT OPTIONAL void *pvStructInfo,
|
|
IN OUT DWORD *pcbStructInfo
|
|
);
|
|
|
|
#ifndef OSS_CRYPT_ASN1
|
|
|
|
//+-------------------------------------------------------------------------
|
|
// Encode / Decode the "UNICODE" Name Info
|
|
//
|
|
// from certstr.cpp
|
|
//--------------------------------------------------------------------------
|
|
extern BOOL WINAPI UnicodeNameInfoEncodeEx(
|
|
IN DWORD dwCertEncodingType,
|
|
IN LPCSTR lpszStructType,
|
|
IN PCERT_NAME_INFO pInfo,
|
|
IN DWORD dwFlags,
|
|
IN OPTIONAL PCRYPT_ENCODE_PARA pEncodePara,
|
|
OUT OPTIONAL void *pvEncoded,
|
|
IN OUT DWORD *pcbEncoded
|
|
);
|
|
extern BOOL WINAPI UnicodeNameInfoDecodeEx(
|
|
IN DWORD dwCertEncodingType,
|
|
IN LPCSTR lpszStructType,
|
|
IN const BYTE *pbEncoded,
|
|
IN DWORD cbEncoded,
|
|
IN DWORD dwFlags,
|
|
IN OPTIONAL PCRYPT_DECODE_PARA pDecodePara,
|
|
OUT OPTIONAL void *pvStructInfo,
|
|
IN OUT DWORD *pcbStructInfo
|
|
);
|
|
|
|
//+-------------------------------------------------------------------------
|
|
// Encode / Decode the "UNICODE" Name Value
|
|
//
|
|
// from certstr.cpp
|
|
//--------------------------------------------------------------------------
|
|
extern BOOL WINAPI UnicodeNameValueEncodeEx(
|
|
IN DWORD dwCertEncodingType,
|
|
IN LPCSTR lpszStructType,
|
|
IN PCERT_NAME_VALUE pInfo,
|
|
IN DWORD dwFlags,
|
|
IN OPTIONAL PCRYPT_ENCODE_PARA pEncodePara,
|
|
OUT OPTIONAL void *pvEncoded,
|
|
IN OUT DWORD *pcbEncoded
|
|
);
|
|
extern BOOL WINAPI UnicodeNameValueDecodeEx(
|
|
IN DWORD dwCertEncodingType,
|
|
IN LPCSTR lpszStructType,
|
|
IN const BYTE *pbEncoded,
|
|
IN DWORD cbEncoded,
|
|
IN DWORD dwFlags,
|
|
IN OPTIONAL PCRYPT_DECODE_PARA pDecodePara,
|
|
OUT OPTIONAL void *pvStructInfo,
|
|
IN OUT DWORD *pcbStructInfo
|
|
);
|
|
|
|
//+-------------------------------------------------------------------------
|
|
// Encode sorted ctl info
|
|
//
|
|
// from newstor.cpp
|
|
//--------------------------------------------------------------------------
|
|
extern BOOL WINAPI SortedCtlInfoEncodeEx(
|
|
IN DWORD dwCertEncodingType,
|
|
IN LPCSTR lpszStructType,
|
|
IN PCTL_INFO pCtlInfo,
|
|
IN DWORD dwFlags,
|
|
IN OPTIONAL PCRYPT_ENCODE_PARA pEncodePara,
|
|
OUT OPTIONAL void *pvEncoded,
|
|
IN OUT DWORD *pcbEncoded
|
|
);
|
|
|
|
#endif // OSS_CRYPT_ASN1
|
|
|
|
#ifdef OSS_CRYPT_ASN1
|
|
#define ASN1_OID_OFFSET 10000 +
|
|
#define ASN1_OID_PREFIX "OssCryptAsn1."
|
|
#else
|
|
#define ASN1_OID_OFFSET
|
|
#define ASN1_OID_PREFIX
|
|
#endif // OSS_CRYPT_ASN1
|
|
|
|
#ifdef DEBUG_CRYPT_ASN1_MASTER
|
|
#define OSS_OID_OFFSET 10000
|
|
#define OSS_OID_PREFIX "OssCryptAsn1."
|
|
#endif // DEBUG_CRYPT_ASN1_MASTER
|
|
|
|
static const CRYPT_OID_FUNC_ENTRY X509EncodeExFuncTable[] = {
|
|
ASN1_OID_OFFSET X509_CERT, Asn1X509SignedContentEncodeEx,
|
|
ASN1_OID_OFFSET X509_CERT_TO_BE_SIGNED, Asn1X509CertInfoEncodeEx,
|
|
ASN1_OID_OFFSET X509_CERT_CRL_TO_BE_SIGNED, Asn1X509CrlInfoEncodeEx,
|
|
ASN1_OID_OFFSET X509_CERT_REQUEST_TO_BE_SIGNED, Asn1X509CertRequestInfoEncodeEx,
|
|
ASN1_OID_OFFSET X509_EXTENSIONS, Asn1X509ExtensionsEncodeEx,
|
|
ASN1_OID_OFFSET X509_NAME_VALUE, Asn1X509NameValueEncodeEx,
|
|
ASN1_OID_OFFSET X509_NAME, Asn1X509NameInfoEncodeEx,
|
|
ASN1_OID_OFFSET X509_PUBLIC_KEY_INFO, Asn1X509PublicKeyInfoEncodeEx,
|
|
ASN1_OID_OFFSET X509_AUTHORITY_KEY_ID, Asn1X509AuthorityKeyIdEncodeEx,
|
|
ASN1_OID_OFFSET X509_KEY_ATTRIBUTES, Asn1X509KeyAttributesEncodeEx,
|
|
ASN1_OID_OFFSET X509_KEY_USAGE_RESTRICTION, Asn1X509KeyUsageRestrictionEncodeEx,
|
|
ASN1_OID_OFFSET X509_ALTERNATE_NAME, Asn1X509AltNameEncodeEx,
|
|
ASN1_OID_OFFSET X509_BASIC_CONSTRAINTS, Asn1X509BasicConstraintsEncodeEx,
|
|
ASN1_OID_OFFSET X509_KEY_USAGE, Asn1X509BitsWithoutTrailingZeroesEncodeEx,
|
|
ASN1_OID_OFFSET X509_BASIC_CONSTRAINTS2, Asn1X509BasicConstraints2EncodeEx,
|
|
ASN1_OID_OFFSET X509_CERT_POLICIES, Asn1X509CertPoliciesEncodeEx,
|
|
ASN1_OID_OFFSET PKCS_UTC_TIME, Asn1UtcTimeEncodeEx,
|
|
ASN1_OID_OFFSET PKCS_TIME_REQUEST, Asn1TimeStampRequestInfoEncodeEx,
|
|
ASN1_OID_OFFSET RSA_CSP_PUBLICKEYBLOB, Asn1RSAPublicKeyStrucEncodeEx,
|
|
#ifndef OSS_CRYPT_ASN1
|
|
ASN1_OID_OFFSET X509_UNICODE_NAME, UnicodeNameInfoEncodeEx,
|
|
#endif // OSS_CRYPT_ASN1
|
|
|
|
ASN1_OID_OFFSET X509_KEYGEN_REQUEST_TO_BE_SIGNED, Asn1X509KeygenRequestInfoEncodeEx,
|
|
ASN1_OID_OFFSET PKCS_ATTRIBUTE, Asn1X509AttributeEncodeEx,
|
|
ASN1_OID_OFFSET PKCS_CONTENT_INFO_SEQUENCE_OF_ANY, Asn1X509ContentInfoSequenceOfAnyEncodeEx,
|
|
#ifndef OSS_CRYPT_ASN1
|
|
ASN1_OID_OFFSET X509_UNICODE_NAME_VALUE, UnicodeNameValueEncodeEx,
|
|
#endif // OSS_CRYPT_ASN1
|
|
ASN1_OID_OFFSET X509_OCTET_STRING, Asn1X509OctetStringEncodeEx,
|
|
ASN1_OID_OFFSET X509_BITS, Asn1X509BitsEncodeEx,
|
|
ASN1_OID_OFFSET X509_INTEGER, Asn1X509IntegerEncodeEx,
|
|
ASN1_OID_OFFSET X509_MULTI_BYTE_INTEGER, Asn1X509MultiByteIntegerEncodeEx,
|
|
ASN1_OID_OFFSET X509_ENUMERATED, Asn1X509EnumeratedEncodeEx,
|
|
ASN1_OID_OFFSET X509_CHOICE_OF_TIME, Asn1X509ChoiceOfTimeEncodeEx,
|
|
ASN1_OID_OFFSET X509_AUTHORITY_KEY_ID2, Asn1X509AuthorityKeyId2EncodeEx,
|
|
ASN1_OID_OFFSET X509_AUTHORITY_INFO_ACCESS, Asn1X509AuthorityInfoAccessEncodeEx,
|
|
ASN1_OID_OFFSET PKCS_CONTENT_INFO, Asn1X509ContentInfoEncodeEx,
|
|
ASN1_OID_OFFSET X509_SEQUENCE_OF_ANY, Asn1X509SequenceOfAnyEncodeEx,
|
|
ASN1_OID_OFFSET X509_CRL_DIST_POINTS, Asn1X509CrlDistPointsEncodeEx,
|
|
|
|
ASN1_OID_OFFSET X509_ENHANCED_KEY_USAGE, Asn1X509CtlUsageEncodeEx,
|
|
ASN1_OID_OFFSET PKCS_CTL, Asn1X509CtlInfoEncodeEx,
|
|
|
|
ASN1_OID_OFFSET X509_MULTI_BYTE_UINT, Asn1X509MultiByteUINTEncodeEx,
|
|
ASN1_OID_OFFSET X509_DSS_PARAMETERS, Asn1X509DSSParametersEncodeEx,
|
|
ASN1_OID_OFFSET X509_DSS_SIGNATURE, Asn1X509DSSSignatureEncodeEx,
|
|
ASN1_OID_OFFSET PKCS_RC2_CBC_PARAMETERS, Asn1RC2CBCParametersEncodeEx,
|
|
ASN1_OID_OFFSET PKCS_SMIME_CAPABILITIES, Asn1SMIMECapabilitiesEncodeEx,
|
|
|
|
ASN1_OID_PREFIX X509_PKIX_POLICY_QUALIFIER_USERNOTICE, Asn1X509PKIXUserNoticeEncodeEx,
|
|
ASN1_OID_OFFSET X509_DH_PARAMETERS, Asn1X509DHParametersEncodeEx,
|
|
ASN1_OID_OFFSET PKCS_ATTRIBUTES, Asn1X509AttributesEncodeEx,
|
|
#ifndef OSS_CRYPT_ASN1
|
|
ASN1_OID_OFFSET PKCS_SORTED_CTL, SortedCtlInfoEncodeEx,
|
|
#endif // OSS_CRYPT_ASN1
|
|
|
|
ASN1_OID_OFFSET X942_DH_PARAMETERS, Asn1X942DhParametersEncodeEx,
|
|
ASN1_OID_OFFSET X509_BITS_WITHOUT_TRAILING_ZEROES, Asn1X509BitsWithoutTrailingZeroesEncodeEx,
|
|
|
|
ASN1_OID_OFFSET X942_OTHER_INFO, Asn1X942OtherInfoEncodeEx,
|
|
ASN1_OID_OFFSET X509_CERT_PAIR, Asn1X509CertPairEncodeEx,
|
|
ASN1_OID_OFFSET X509_ISSUING_DIST_POINT, Asn1X509CrlIssuingDistPointEncodeEx,
|
|
ASN1_OID_OFFSET X509_NAME_CONSTRAINTS, Asn1X509NameConstraintsEncodeEx,
|
|
ASN1_OID_OFFSET X509_POLICY_MAPPINGS, Asn1X509PolicyMappingsEncodeEx,
|
|
ASN1_OID_OFFSET X509_POLICY_CONSTRAINTS, Asn1X509PolicyConstraintsEncodeEx,
|
|
ASN1_OID_OFFSET X509_CROSS_CERT_DIST_POINTS, Asn1X509CrossCertDistPointsEncodeEx,
|
|
|
|
ASN1_OID_OFFSET CMC_DATA, Asn1CmcDataEncodeEx,
|
|
ASN1_OID_OFFSET CMC_RESPONSE, Asn1CmcResponseEncodeEx,
|
|
ASN1_OID_OFFSET CMC_STATUS, Asn1CmcStatusEncodeEx,
|
|
ASN1_OID_OFFSET CMC_ADD_EXTENSIONS, Asn1CmcAddExtensionsEncodeEx,
|
|
ASN1_OID_OFFSET CMC_ADD_ATTRIBUTES, Asn1CmcAddAttributesEncodeEx,
|
|
ASN1_OID_OFFSET X509_CERTIFICATE_TEMPLATE, Asn1X509CertTemplateEncodeEx,
|
|
|
|
ASN1_OID_PREFIX szOID_AUTHORITY_KEY_IDENTIFIER, Asn1X509AuthorityKeyIdEncodeEx,
|
|
ASN1_OID_PREFIX szOID_KEY_ATTRIBUTES, Asn1X509KeyAttributesEncodeEx,
|
|
ASN1_OID_PREFIX szOID_KEY_USAGE_RESTRICTION, Asn1X509KeyUsageRestrictionEncodeEx,
|
|
ASN1_OID_PREFIX szOID_SUBJECT_ALT_NAME, Asn1X509AltNameEncodeEx,
|
|
ASN1_OID_PREFIX szOID_ISSUER_ALT_NAME, Asn1X509AltNameEncodeEx,
|
|
ASN1_OID_PREFIX szOID_BASIC_CONSTRAINTS, Asn1X509BasicConstraintsEncodeEx,
|
|
ASN1_OID_PREFIX szOID_KEY_USAGE, Asn1X509BitsWithoutTrailingZeroesEncodeEx,
|
|
ASN1_OID_PREFIX szOID_BASIC_CONSTRAINTS2, Asn1X509BasicConstraints2EncodeEx,
|
|
ASN1_OID_PREFIX szOID_CERT_POLICIES, Asn1X509CertPoliciesEncodeEx,
|
|
|
|
ASN1_OID_PREFIX szOID_PKIX_POLICY_QUALIFIER_USERNOTICE, Asn1X509PKIXUserNoticeEncodeEx,
|
|
|
|
ASN1_OID_PREFIX szOID_AUTHORITY_KEY_IDENTIFIER2, Asn1X509AuthorityKeyId2EncodeEx,
|
|
ASN1_OID_PREFIX szOID_SUBJECT_KEY_IDENTIFIER, Asn1X509OctetStringEncodeEx,
|
|
ASN1_OID_PREFIX szOID_SUBJECT_ALT_NAME2, Asn1X509AltNameEncodeEx,
|
|
ASN1_OID_PREFIX szOID_ISSUER_ALT_NAME2, Asn1X509AltNameEncodeEx,
|
|
ASN1_OID_PREFIX szOID_CRL_REASON_CODE, Asn1X509EnumeratedEncodeEx,
|
|
ASN1_OID_PREFIX szOID_AUTHORITY_INFO_ACCESS, Asn1X509AuthorityInfoAccessEncodeEx,
|
|
ASN1_OID_PREFIX szOID_CRL_DIST_POINTS, Asn1X509CrlDistPointsEncodeEx,
|
|
|
|
ASN1_OID_PREFIX szOID_CERT_EXTENSIONS, Asn1X509ExtensionsEncodeEx,
|
|
ASN1_OID_PREFIX szOID_RSA_certExtensions, Asn1X509ExtensionsEncodeEx,
|
|
ASN1_OID_PREFIX szOID_NEXT_UPDATE_LOCATION, Asn1X509AltNameEncodeEx,
|
|
|
|
ASN1_OID_PREFIX szOID_ENHANCED_KEY_USAGE, Asn1X509CtlUsageEncodeEx,
|
|
ASN1_OID_PREFIX szOID_CTL, Asn1X509CtlInfoEncodeEx,
|
|
|
|
ASN1_OID_PREFIX szOID_RSA_RC2CBC, Asn1RC2CBCParametersEncodeEx,
|
|
ASN1_OID_PREFIX szOID_RSA_SMIMECapabilities, Asn1SMIMECapabilitiesEncodeEx,
|
|
ASN1_OID_PREFIX szOID_RSA_signingTime, Asn1UtcTimeEncodeEx,
|
|
|
|
ASN1_OID_PREFIX szOID_ENROLLMENT_NAME_VALUE_PAIR, Asn1NameValueEncodeEx,
|
|
szOID_ENROLLMENT_CSP_PROVIDER, Asn1CSPProviderEncodeEx,
|
|
|
|
ASN1_OID_OFFSET szOID_CRL_NUMBER, Asn1X509IntegerEncodeEx,
|
|
ASN1_OID_OFFSET szOID_DELTA_CRL_INDICATOR, Asn1X509IntegerEncodeEx,
|
|
ASN1_OID_OFFSET szOID_ISSUING_DIST_POINT, Asn1X509CrlIssuingDistPointEncodeEx,
|
|
ASN1_OID_PREFIX szOID_FRESHEST_CRL, Asn1X509CrlDistPointsEncodeEx,
|
|
ASN1_OID_OFFSET szOID_NAME_CONSTRAINTS, Asn1X509NameConstraintsEncodeEx,
|
|
ASN1_OID_OFFSET szOID_POLICY_MAPPINGS, Asn1X509PolicyMappingsEncodeEx,
|
|
ASN1_OID_OFFSET szOID_LEGACY_POLICY_MAPPINGS, Asn1X509PolicyMappingsEncodeEx,
|
|
ASN1_OID_OFFSET szOID_POLICY_CONSTRAINTS, Asn1X509PolicyConstraintsEncodeEx,
|
|
ASN1_OID_OFFSET szOID_CROSS_CERT_DIST_POINTS, Asn1X509CrossCertDistPointsEncodeEx,
|
|
ASN1_OID_OFFSET szOID_CERTIFICATE_TEMPLATE, Asn1X509CertTemplateEncodeEx,
|
|
|
|
};
|
|
|
|
#define X509_ENCODE_EX_FUNC_COUNT (sizeof(X509EncodeExFuncTable) / \
|
|
sizeof(X509EncodeExFuncTable[0]))
|
|
|
|
static const CRYPT_OID_FUNC_ENTRY X509DecodeExFuncTable[] = {
|
|
ASN1_OID_OFFSET X509_CERT, Asn1X509SignedContentDecodeEx,
|
|
ASN1_OID_OFFSET X509_CERT_TO_BE_SIGNED, Asn1X509CertInfoDecodeEx,
|
|
ASN1_OID_OFFSET X509_CERT_CRL_TO_BE_SIGNED, Asn1X509CrlInfoDecodeEx,
|
|
ASN1_OID_OFFSET X509_CERT_REQUEST_TO_BE_SIGNED, Asn1X509CertRequestInfoDecodeEx,
|
|
ASN1_OID_OFFSET X509_EXTENSIONS, Asn1X509ExtensionsDecodeEx,
|
|
ASN1_OID_OFFSET X509_NAME_VALUE, Asn1X509NameValueDecodeEx,
|
|
ASN1_OID_OFFSET X509_NAME, Asn1X509NameInfoDecodeEx,
|
|
ASN1_OID_OFFSET X509_PUBLIC_KEY_INFO, Asn1X509PublicKeyInfoDecodeEx,
|
|
ASN1_OID_OFFSET X509_AUTHORITY_KEY_ID, Asn1X509AuthorityKeyIdDecodeEx,
|
|
ASN1_OID_OFFSET X509_KEY_ATTRIBUTES, Asn1X509KeyAttributesDecodeEx,
|
|
ASN1_OID_OFFSET X509_KEY_USAGE_RESTRICTION, Asn1X509KeyUsageRestrictionDecodeEx,
|
|
ASN1_OID_OFFSET X509_ALTERNATE_NAME, Asn1X509AltNameDecodeEx,
|
|
ASN1_OID_OFFSET X509_BASIC_CONSTRAINTS, Asn1X509BasicConstraintsDecodeEx,
|
|
ASN1_OID_OFFSET X509_KEY_USAGE, Asn1X509BitsDecodeEx,
|
|
ASN1_OID_OFFSET X509_BASIC_CONSTRAINTS2, Asn1X509BasicConstraints2DecodeEx,
|
|
ASN1_OID_OFFSET X509_CERT_POLICIES, Asn1X509CertPoliciesDecodeEx,
|
|
ASN1_OID_OFFSET PKCS_UTC_TIME, Asn1UtcTimeDecodeEx,
|
|
ASN1_OID_OFFSET PKCS_TIME_REQUEST, Asn1TimeStampRequestInfoDecodeEx,
|
|
ASN1_OID_OFFSET RSA_CSP_PUBLICKEYBLOB, Asn1RSAPublicKeyStrucDecodeEx,
|
|
#ifndef OSS_CRYPT_ASN1
|
|
ASN1_OID_OFFSET X509_UNICODE_NAME, UnicodeNameInfoDecodeEx,
|
|
#endif // OSS_CRYPT_ASN1
|
|
|
|
ASN1_OID_OFFSET X509_KEYGEN_REQUEST_TO_BE_SIGNED, Asn1X509KeygenRequestInfoDecodeEx,
|
|
ASN1_OID_OFFSET PKCS_ATTRIBUTE, Asn1X509AttributeDecodeEx,
|
|
ASN1_OID_OFFSET PKCS_CONTENT_INFO_SEQUENCE_OF_ANY, Asn1X509ContentInfoSequenceOfAnyDecodeEx,
|
|
#ifndef OSS_CRYPT_ASN1
|
|
ASN1_OID_OFFSET X509_UNICODE_NAME_VALUE, UnicodeNameValueDecodeEx,
|
|
#endif // OSS_CRYPT_ASN1
|
|
ASN1_OID_OFFSET X509_OCTET_STRING, Asn1X509OctetStringDecodeEx,
|
|
ASN1_OID_OFFSET X509_BITS, Asn1X509BitsDecodeEx,
|
|
ASN1_OID_OFFSET X509_INTEGER, Asn1X509IntegerDecodeEx,
|
|
ASN1_OID_OFFSET X509_MULTI_BYTE_INTEGER, Asn1X509MultiByteIntegerDecodeEx,
|
|
ASN1_OID_OFFSET X509_ENUMERATED, Asn1X509EnumeratedDecodeEx,
|
|
ASN1_OID_OFFSET X509_CHOICE_OF_TIME, Asn1X509ChoiceOfTimeDecodeEx,
|
|
ASN1_OID_OFFSET X509_AUTHORITY_KEY_ID2, Asn1X509AuthorityKeyId2DecodeEx,
|
|
ASN1_OID_OFFSET X509_AUTHORITY_INFO_ACCESS, Asn1X509AuthorityInfoAccessDecodeEx,
|
|
ASN1_OID_OFFSET PKCS_CONTENT_INFO, Asn1X509ContentInfoDecodeEx,
|
|
ASN1_OID_OFFSET X509_SEQUENCE_OF_ANY, Asn1X509SequenceOfAnyDecodeEx,
|
|
ASN1_OID_OFFSET X509_CRL_DIST_POINTS, Asn1X509CrlDistPointsDecodeEx,
|
|
|
|
ASN1_OID_OFFSET X509_ENHANCED_KEY_USAGE, Asn1X509CtlUsageDecodeEx,
|
|
ASN1_OID_OFFSET PKCS_CTL, Asn1X509CtlInfoDecodeEx,
|
|
|
|
ASN1_OID_OFFSET X509_MULTI_BYTE_UINT, Asn1X509MultiByteUINTDecodeEx,
|
|
ASN1_OID_OFFSET X509_DSS_PARAMETERS, Asn1X509DSSParametersDecodeEx,
|
|
ASN1_OID_OFFSET X509_DSS_SIGNATURE, Asn1X509DSSSignatureDecodeEx,
|
|
ASN1_OID_OFFSET PKCS_RC2_CBC_PARAMETERS, Asn1RC2CBCParametersDecodeEx,
|
|
ASN1_OID_OFFSET PKCS_SMIME_CAPABILITIES, Asn1SMIMECapabilitiesDecodeEx,
|
|
|
|
ASN1_OID_PREFIX X509_PKIX_POLICY_QUALIFIER_USERNOTICE, Asn1X509PKIXUserNoticeDecodeEx,
|
|
ASN1_OID_OFFSET X509_DH_PARAMETERS, Asn1X509DHParametersDecodeEx,
|
|
ASN1_OID_OFFSET PKCS_ATTRIBUTES, Asn1X509AttributesDecodeEx,
|
|
#ifndef OSS_CRYPT_ASN1
|
|
ASN1_OID_OFFSET PKCS_SORTED_CTL, Asn1X509CtlInfoDecodeEx,
|
|
#endif // OSS_CRYPT_ASN1
|
|
|
|
ASN1_OID_OFFSET X942_DH_PARAMETERS, Asn1X942DhParametersDecodeEx,
|
|
ASN1_OID_OFFSET X509_BITS_WITHOUT_TRAILING_ZEROES, Asn1X509BitsDecodeEx,
|
|
|
|
ASN1_OID_OFFSET X942_OTHER_INFO, Asn1X942OtherInfoDecodeEx,
|
|
ASN1_OID_OFFSET X509_CERT_PAIR, Asn1X509CertPairDecodeEx,
|
|
ASN1_OID_OFFSET X509_ISSUING_DIST_POINT, Asn1X509CrlIssuingDistPointDecodeEx,
|
|
ASN1_OID_OFFSET X509_NAME_CONSTRAINTS, Asn1X509NameConstraintsDecodeEx,
|
|
ASN1_OID_OFFSET X509_POLICY_MAPPINGS, Asn1X509PolicyMappingsDecodeEx,
|
|
ASN1_OID_OFFSET X509_POLICY_CONSTRAINTS, Asn1X509PolicyConstraintsDecodeEx,
|
|
ASN1_OID_OFFSET X509_CROSS_CERT_DIST_POINTS, Asn1X509CrossCertDistPointsDecodeEx,
|
|
|
|
ASN1_OID_OFFSET CMC_DATA, Asn1CmcDataDecodeEx,
|
|
ASN1_OID_OFFSET CMC_RESPONSE, Asn1CmcResponseDecodeEx,
|
|
ASN1_OID_OFFSET CMC_STATUS, Asn1CmcStatusDecodeEx,
|
|
ASN1_OID_OFFSET CMC_ADD_EXTENSIONS, Asn1CmcAddExtensionsDecodeEx,
|
|
ASN1_OID_OFFSET CMC_ADD_ATTRIBUTES, Asn1CmcAddAttributesDecodeEx,
|
|
ASN1_OID_OFFSET X509_CERTIFICATE_TEMPLATE, Asn1X509CertTemplateDecodeEx,
|
|
|
|
ASN1_OID_PREFIX szOID_AUTHORITY_KEY_IDENTIFIER, Asn1X509AuthorityKeyIdDecodeEx,
|
|
ASN1_OID_PREFIX szOID_KEY_ATTRIBUTES, Asn1X509KeyAttributesDecodeEx,
|
|
ASN1_OID_PREFIX szOID_KEY_USAGE_RESTRICTION, Asn1X509KeyUsageRestrictionDecodeEx,
|
|
ASN1_OID_PREFIX szOID_SUBJECT_ALT_NAME, Asn1X509AltNameDecodeEx,
|
|
ASN1_OID_PREFIX szOID_ISSUER_ALT_NAME, Asn1X509AltNameDecodeEx,
|
|
ASN1_OID_PREFIX szOID_BASIC_CONSTRAINTS, Asn1X509BasicConstraintsDecodeEx,
|
|
ASN1_OID_PREFIX szOID_KEY_USAGE, Asn1X509BitsDecodeEx,
|
|
ASN1_OID_PREFIX szOID_BASIC_CONSTRAINTS2, Asn1X509BasicConstraints2DecodeEx,
|
|
ASN1_OID_PREFIX szOID_CERT_POLICIES, Asn1X509CertPoliciesDecodeEx,
|
|
ASN1_OID_PREFIX szOID_CERT_POLICIES_95, Asn1X509CertPoliciesDecodeEx,
|
|
ASN1_OID_PREFIX szOID_CERT_POLICIES_95_QUALIFIER1, Asn1X509CertPoliciesQualifier1DecodeEx,
|
|
|
|
ASN1_OID_PREFIX szOID_PKIX_POLICY_QUALIFIER_USERNOTICE, Asn1X509PKIXUserNoticeDecodeEx,
|
|
|
|
ASN1_OID_PREFIX szOID_AUTHORITY_KEY_IDENTIFIER2, Asn1X509AuthorityKeyId2DecodeEx,
|
|
ASN1_OID_PREFIX szOID_SUBJECT_KEY_IDENTIFIER, Asn1X509OctetStringDecodeEx,
|
|
ASN1_OID_PREFIX szOID_SUBJECT_ALT_NAME2, Asn1X509AltNameDecodeEx,
|
|
ASN1_OID_PREFIX szOID_ISSUER_ALT_NAME2, Asn1X509AltNameDecodeEx,
|
|
ASN1_OID_PREFIX szOID_CRL_REASON_CODE, Asn1X509EnumeratedDecodeEx,
|
|
ASN1_OID_PREFIX szOID_AUTHORITY_INFO_ACCESS, Asn1X509AuthorityInfoAccessDecodeEx,
|
|
ASN1_OID_PREFIX szOID_CRL_DIST_POINTS, Asn1X509CrlDistPointsDecodeEx,
|
|
|
|
ASN1_OID_PREFIX szOID_CERT_EXTENSIONS, Asn1X509ExtensionsDecodeEx,
|
|
ASN1_OID_PREFIX szOID_RSA_certExtensions, Asn1X509ExtensionsDecodeEx,
|
|
ASN1_OID_PREFIX szOID_NEXT_UPDATE_LOCATION, Asn1X509AltNameDecodeEx,
|
|
|
|
ASN1_OID_PREFIX szOID_ENHANCED_KEY_USAGE, Asn1X509CtlUsageDecodeEx,
|
|
ASN1_OID_PREFIX szOID_CTL, Asn1X509CtlInfoDecodeEx,
|
|
|
|
ASN1_OID_PREFIX szOID_RSA_RC2CBC, Asn1RC2CBCParametersDecodeEx,
|
|
ASN1_OID_PREFIX szOID_RSA_SMIMECapabilities, Asn1SMIMECapabilitiesDecodeEx,
|
|
ASN1_OID_PREFIX szOID_RSA_signingTime, Asn1UtcTimeDecodeEx,
|
|
|
|
ASN1_OID_PREFIX szOID_ENROLLMENT_NAME_VALUE_PAIR, Asn1NameValueDecodeEx,
|
|
ASN1_OID_PREFIX szOID_ENROLLMENT_CSP_PROVIDER, Asn1CSPProviderDecodeEx,
|
|
|
|
ASN1_OID_OFFSET szOID_CRL_NUMBER, Asn1X509IntegerDecodeEx,
|
|
ASN1_OID_OFFSET szOID_DELTA_CRL_INDICATOR, Asn1X509IntegerDecodeEx,
|
|
ASN1_OID_OFFSET szOID_ISSUING_DIST_POINT, Asn1X509CrlIssuingDistPointDecodeEx,
|
|
ASN1_OID_PREFIX szOID_FRESHEST_CRL, Asn1X509CrlDistPointsDecodeEx,
|
|
ASN1_OID_OFFSET szOID_NAME_CONSTRAINTS, Asn1X509NameConstraintsDecodeEx,
|
|
ASN1_OID_OFFSET szOID_POLICY_MAPPINGS, Asn1X509PolicyMappingsDecodeEx,
|
|
ASN1_OID_OFFSET szOID_LEGACY_POLICY_MAPPINGS, Asn1X509PolicyMappingsDecodeEx,
|
|
ASN1_OID_OFFSET szOID_POLICY_CONSTRAINTS, Asn1X509PolicyConstraintsDecodeEx,
|
|
ASN1_OID_OFFSET szOID_CROSS_CERT_DIST_POINTS, Asn1X509CrossCertDistPointsDecodeEx,
|
|
ASN1_OID_OFFSET szOID_CERTIFICATE_TEMPLATE, Asn1X509CertTemplateDecodeEx,
|
|
};
|
|
|
|
#define X509_DECODE_EX_FUNC_COUNT (sizeof(X509DecodeExFuncTable) / \
|
|
sizeof(X509DecodeExFuncTable[0]))
|
|
|
|
#ifdef DEBUG_CRYPT_ASN1_MASTER
|
|
static HMODULE hOssCryptDll = NULL;
|
|
#endif // DEBUG_CRYPT_ASN1_MASTER
|
|
|
|
BOOL
|
|
WINAPI
|
|
CertASNDllMain(
|
|
HMODULE hInst,
|
|
ULONG ulReason,
|
|
LPVOID lpReserved)
|
|
{
|
|
BOOL fRet;
|
|
|
|
if (!I_CryptOIDConvDllMain(hInst, ulReason, lpReserved))
|
|
return FALSE;
|
|
|
|
switch (ulReason) {
|
|
case DLL_PROCESS_ATTACH:
|
|
if (NULL == (hX509EncodeFuncSet = CryptInitOIDFunctionSet(
|
|
CRYPT_OID_ENCODE_OBJECT_FUNC,
|
|
0)))
|
|
goto CryptInitOIDFunctionSetError;
|
|
if (NULL == (hX509DecodeFuncSet = CryptInitOIDFunctionSet(
|
|
CRYPT_OID_DECODE_OBJECT_FUNC,
|
|
0)))
|
|
goto CryptInitOIDFunctionSetError;
|
|
|
|
if (NULL == (hX509EncodeExFuncSet = CryptInitOIDFunctionSet(
|
|
CRYPT_OID_ENCODE_OBJECT_EX_FUNC,
|
|
0)))
|
|
goto CryptInitOIDFunctionSetError;
|
|
if (NULL == (hX509DecodeExFuncSet = CryptInitOIDFunctionSet(
|
|
CRYPT_OID_DECODE_OBJECT_EX_FUNC,
|
|
0)))
|
|
goto CryptInitOIDFunctionSetError;
|
|
|
|
if (!CryptInstallOIDFunctionAddress(
|
|
NULL, // hModule
|
|
X509_ASN_ENCODING,
|
|
CRYPT_OID_ENCODE_OBJECT_EX_FUNC,
|
|
X509_ENCODE_EX_FUNC_COUNT,
|
|
X509EncodeExFuncTable,
|
|
0)) // dwFlags
|
|
goto CryptInstallOIDFunctionAddressError;
|
|
if (!CryptInstallOIDFunctionAddress(
|
|
NULL, // hModule
|
|
X509_ASN_ENCODING,
|
|
CRYPT_OID_DECODE_OBJECT_EX_FUNC,
|
|
X509_DECODE_EX_FUNC_COUNT,
|
|
X509DecodeExFuncTable,
|
|
0)) // dwFlags
|
|
goto CryptInstallOIDFunctionAddressError;
|
|
|
|
#ifdef OSS_CRYPT_ASN1
|
|
if (0 == (hX509Asn1Module = I_CryptInstallAsn1Module(ossx509, 0, NULL)))
|
|
goto CryptInstallAsn1ModuleError;
|
|
#else
|
|
X509_Module_Startup();
|
|
if (0 == (hX509Asn1Module = I_CryptInstallAsn1Module(
|
|
X509_Module, 0, NULL))) {
|
|
X509_Module_Cleanup();
|
|
goto CryptInstallAsn1ModuleError;
|
|
}
|
|
#endif // OSS_CRYPT_ASN1
|
|
break;
|
|
|
|
case DLL_PROCESS_DETACH:
|
|
#ifdef DEBUG_CRYPT_ASN1_MASTER
|
|
if (hOssCryptDll) {
|
|
FreeLibrary(hOssCryptDll);
|
|
hOssCryptDll = NULL;
|
|
}
|
|
#endif // DEBUG_CRYPT_ASN1_MASTER
|
|
|
|
I_CryptUninstallAsn1Module(hX509Asn1Module);
|
|
#ifndef OSS_CRYPT_ASN1
|
|
X509_Module_Cleanup();
|
|
#endif // OSS_CRYPT_ASN1
|
|
case DLL_THREAD_DETACH:
|
|
default:
|
|
break;
|
|
}
|
|
|
|
fRet = TRUE;
|
|
CommonReturn:
|
|
return fRet;
|
|
|
|
ErrorReturn:
|
|
I_CryptOIDConvDllMain(hInst, DLL_PROCESS_DETACH, NULL);
|
|
fRet = FALSE;
|
|
goto CommonReturn;
|
|
TRACE_ERROR(CryptInstallAsn1ModuleError)
|
|
TRACE_ERROR(CryptInitOIDFunctionSetError)
|
|
TRACE_ERROR(CryptInstallOIDFunctionAddressError)
|
|
}
|
|
|
|
#ifdef DEBUG_CRYPT_ASN1_MASTER
|
|
|
|
#define DEBUG_OSS_CRYPT_ASN1_ENCODE_FLAG 0x1
|
|
#define DEBUG_OSS_CRYPT_ASN1_DECODE_FLAG 0x2
|
|
#define DEBUG_OSS_CRYPT_ASN1_COMPARE_FLAG 0x4
|
|
|
|
static BOOL fGotDebugCryptAsn1Flags = FALSE;
|
|
static int iDebugCryptAsn1Flags = 0;
|
|
|
|
int
|
|
WINAPI
|
|
GetDebugCryptAsn1Flags()
|
|
{
|
|
|
|
if (!fGotDebugCryptAsn1Flags) {
|
|
char *pszEnvVar;
|
|
char *p;
|
|
int iFlags;
|
|
|
|
if (pszEnvVar = getenv("DEBUG_CRYPT_ASN1_FLAGS"))
|
|
iFlags = strtol(pszEnvVar, &p, 16);
|
|
else
|
|
iFlags = DEBUG_OSS_CRYPT_ASN1_COMPARE_FLAG;
|
|
|
|
if (iFlags) {
|
|
if (NULL == (hOssCryptDll = LoadLibraryA("osscrypt.dll"))) {
|
|
iFlags = 0;
|
|
if (pszEnvVar)
|
|
MessageBoxA(
|
|
NULL, // hwndOwner
|
|
"LoadLibrary(osscrypt.dll) failed",
|
|
"CheckCryptEncodeDecodeAsn1",
|
|
MB_TOPMOST | MB_OK | MB_ICONWARNING |
|
|
MB_SERVICE_NOTIFICATION
|
|
);
|
|
}
|
|
}
|
|
|
|
iDebugCryptAsn1Flags = iFlags;
|
|
fGotDebugCryptAsn1Flags = TRUE;
|
|
}
|
|
return iDebugCryptAsn1Flags;
|
|
}
|
|
|
|
//+-------------------------------------------------------------------------
|
|
// Write an encoded DER blob to a file
|
|
//--------------------------------------------------------------------------
|
|
static BOOL WriteDERToFile(
|
|
LPCSTR pszFileName,
|
|
PBYTE pbDER,
|
|
DWORD cbDER
|
|
)
|
|
{
|
|
BOOL fResult;
|
|
|
|
// Write the Encoded Blob to the file
|
|
HANDLE hFile;
|
|
hFile = CreateFile(pszFileName,
|
|
GENERIC_WRITE,
|
|
0, // fdwShareMode
|
|
NULL, // lpsa
|
|
CREATE_ALWAYS,
|
|
0, // fdwAttrsAndFlags
|
|
0); // TemplateFile
|
|
if (INVALID_HANDLE_VALUE == hFile) {
|
|
fResult = FALSE;
|
|
} else {
|
|
DWORD dwBytesWritten;
|
|
fResult = WriteFile(
|
|
hFile,
|
|
pbDER,
|
|
cbDER,
|
|
&dwBytesWritten,
|
|
NULL // lpOverlapped
|
|
);
|
|
CloseHandle(hFile);
|
|
}
|
|
return fResult;
|
|
}
|
|
|
|
#endif // DEBUG_CRYPT_ASN1_MASTER
|
|
|
|
//+-------------------------------------------------------------------------
|
|
// Encode the specified data structure according to the certificate
|
|
// encoding type.
|
|
//--------------------------------------------------------------------------
|
|
BOOL
|
|
WINAPI
|
|
CryptEncodeObjectEx(
|
|
IN DWORD dwCertEncodingType,
|
|
IN LPCSTR lpszStructType,
|
|
IN const void *pvStructInfo,
|
|
IN DWORD dwFlags,
|
|
IN OPTIONAL PCRYPT_ENCODE_PARA pEncodePara,
|
|
OUT void *pvEncoded,
|
|
IN OUT DWORD *pcbEncoded
|
|
)
|
|
{
|
|
BOOL fResult;
|
|
void *pvFuncAddr;
|
|
HCRYPTOIDFUNCADDR hFuncAddr = NULL;
|
|
|
|
#ifdef DEBUG_CRYPT_ASN1_MASTER
|
|
int iOssAsn1Flags;
|
|
LPSTR lpszOssAsn1StructType = NULL;
|
|
char szOssOID[128];
|
|
HCRYPTOIDFUNCADDR hOssAsn1FuncAddr = NULL;
|
|
void *pvOssAsn1FuncAddr = NULL;
|
|
|
|
iOssAsn1Flags = GetDebugCryptAsn1Flags() &
|
|
(DEBUG_OSS_CRYPT_ASN1_ENCODE_FLAG |
|
|
DEBUG_OSS_CRYPT_ASN1_COMPARE_FLAG);
|
|
if (iOssAsn1Flags) {
|
|
if (0xFFFF < (DWORD_PTR) lpszStructType) {
|
|
if ((DWORD) strlen(lpszStructType) <
|
|
(sizeof(szOssOID) - strlen(OSS_OID_PREFIX) - 1)) {
|
|
strcpy(szOssOID, OSS_OID_PREFIX);
|
|
strcat(szOssOID, lpszStructType);
|
|
lpszOssAsn1StructType = szOssOID;
|
|
}
|
|
} else
|
|
lpszOssAsn1StructType = (LPSTR) lpszStructType +
|
|
OSS_OID_OFFSET;
|
|
|
|
if (lpszOssAsn1StructType) {
|
|
if (!CryptGetOIDFunctionAddress(
|
|
hX509EncodeExFuncSet,
|
|
dwCertEncodingType,
|
|
lpszOssAsn1StructType,
|
|
0, // dwFlags
|
|
&pvOssAsn1FuncAddr,
|
|
&hOssAsn1FuncAddr
|
|
))
|
|
pvOssAsn1FuncAddr = NULL;
|
|
}
|
|
}
|
|
|
|
if (pvOssAsn1FuncAddr &&
|
|
0 == (iOssAsn1Flags & DEBUG_OSS_CRYPT_ASN1_COMPARE_FLAG)) {
|
|
fResult = ((PFN_ENCODE_EX_FUNC) pvOssAsn1FuncAddr)(
|
|
dwCertEncodingType,
|
|
lpszStructType,
|
|
pvStructInfo,
|
|
dwFlags,
|
|
pEncodePara,
|
|
pvEncoded,
|
|
pcbEncoded
|
|
);
|
|
} else
|
|
#endif // DEBUG_CRYPT_ASN1_MASTER
|
|
|
|
if (CryptGetOIDFunctionAddress(
|
|
hX509EncodeExFuncSet,
|
|
dwCertEncodingType,
|
|
lpszStructType,
|
|
0, // dwFlags
|
|
&pvFuncAddr,
|
|
&hFuncAddr)) {
|
|
__try {
|
|
fResult = ((PFN_ENCODE_EX_FUNC) pvFuncAddr)(
|
|
dwCertEncodingType,
|
|
lpszStructType,
|
|
pvStructInfo,
|
|
dwFlags,
|
|
pEncodePara,
|
|
pvEncoded,
|
|
pcbEncoded
|
|
);
|
|
} __except(EXCEPTION_EXECUTE_HANDLER) {
|
|
fResult = FALSE;
|
|
*pcbEncoded = 0;
|
|
SetLastError(GetExceptionCode());
|
|
}
|
|
|
|
#ifdef DEBUG_CRYPT_ASN1_MASTER
|
|
if (pvOssAsn1FuncAddr && fResult && pvEncoded) {
|
|
BYTE *pbEncoded;
|
|
BOOL fOssAsn1Result;
|
|
BYTE *pbOssAsn1 = NULL;
|
|
DWORD cbOssAsn1;
|
|
|
|
|
|
if (dwFlags & CRYPT_ENCODE_ALLOC_FLAG)
|
|
pbEncoded = *((BYTE **)pvEncoded);
|
|
else
|
|
pbEncoded = (BYTE *) pvEncoded;
|
|
|
|
fOssAsn1Result = ((PFN_ENCODE_EX_FUNC) pvOssAsn1FuncAddr)(
|
|
dwCertEncodingType,
|
|
lpszStructType,
|
|
pvStructInfo,
|
|
dwFlags | CRYPT_ENCODE_ALLOC_FLAG,
|
|
&PkiEncodePara,
|
|
(void *) &pbOssAsn1,
|
|
&cbOssAsn1
|
|
);
|
|
|
|
if (!fOssAsn1Result) {
|
|
int id;
|
|
|
|
id = MessageBoxA(
|
|
NULL, // hwndOwner
|
|
"OssCryptAsn1 encode failed. Select Cancel to stop future OssCryptAsn1 encodes",
|
|
"CheckCryptEncodeDecodeAsn1",
|
|
MB_TOPMOST | MB_OKCANCEL | MB_ICONQUESTION |
|
|
MB_SERVICE_NOTIFICATION
|
|
);
|
|
if (IDCANCEL == id)
|
|
iDebugCryptAsn1Flags = 0;
|
|
} else if (*pcbEncoded != cbOssAsn1 ||
|
|
0 != memcmp(pbEncoded, pbOssAsn1, cbOssAsn1)) {
|
|
int id;
|
|
|
|
WriteDERToFile("msasn1.der", pbEncoded, *pcbEncoded);
|
|
WriteDERToFile("ossasn1.der", pbOssAsn1, cbOssAsn1);
|
|
|
|
id = MessageBoxA(
|
|
NULL, // hwndOwner
|
|
"OssCryptAsn1 encode compare failed. Check ossasn1.der and msasn1.der. Select Cancel to stop future OssCryptAsn1 encodes",
|
|
"CheckCryptEncodeDecodeAsn1",
|
|
MB_TOPMOST | MB_OKCANCEL | MB_ICONQUESTION |
|
|
MB_SERVICE_NOTIFICATION
|
|
);
|
|
if (IDCANCEL == id)
|
|
iDebugCryptAsn1Flags = 0;
|
|
}
|
|
|
|
if (pbOssAsn1)
|
|
PkiFree(pbOssAsn1);
|
|
}
|
|
#endif // DEBUG_CRYPT_ASN1_MASTER
|
|
} else {
|
|
BYTE *pbEncoded;
|
|
|
|
#ifdef DEBUG_CRYPT_ASN1_MASTER
|
|
if (lpszOssAsn1StructType) {
|
|
if (hOssAsn1FuncAddr)
|
|
CryptFreeOIDFunctionAddress(hOssAsn1FuncAddr, 0);
|
|
|
|
if (!CryptGetOIDFunctionAddress(
|
|
hX509EncodeFuncSet,
|
|
dwCertEncodingType,
|
|
lpszOssAsn1StructType,
|
|
0, // dwFlags
|
|
&pvOssAsn1FuncAddr,
|
|
&hOssAsn1FuncAddr
|
|
))
|
|
pvOssAsn1FuncAddr = NULL;
|
|
}
|
|
#endif // DEBUG_CRYPT_ASN1_MASTER
|
|
|
|
if (dwFlags & CRYPT_ENCODE_ALLOC_FLAG)
|
|
*((void **) pvEncoded) = NULL;
|
|
if (dwFlags & ~CRYPT_ENCODE_ALLOC_FLAG)
|
|
goto InvalidFlags;
|
|
|
|
#ifdef DEBUG_CRYPT_ASN1_MASTER
|
|
if (pvOssAsn1FuncAddr &&
|
|
0 == (iOssAsn1Flags & DEBUG_OSS_CRYPT_ASN1_COMPARE_FLAG)) {
|
|
pvFuncAddr = pvOssAsn1FuncAddr;
|
|
pvOssAsn1FuncAddr = NULL;
|
|
hFuncAddr = hOssAsn1FuncAddr;
|
|
hOssAsn1FuncAddr = NULL;
|
|
} else
|
|
#endif // DEBUG_CRYPT_ASN1_MASTER
|
|
if (!CryptGetOIDFunctionAddress(
|
|
hX509EncodeFuncSet,
|
|
dwCertEncodingType,
|
|
lpszStructType,
|
|
0, // dwFlags
|
|
&pvFuncAddr,
|
|
&hFuncAddr))
|
|
goto NoEncodeFunction;
|
|
if (dwFlags & CRYPT_ENCODE_ALLOC_FLAG) {
|
|
PFN_CRYPT_ALLOC pfnAlloc;
|
|
|
|
*pcbEncoded = 0;
|
|
__try {
|
|
fResult = ((PFN_ENCODE_FUNC) pvFuncAddr)(
|
|
dwCertEncodingType,
|
|
lpszStructType,
|
|
pvStructInfo,
|
|
NULL,
|
|
pcbEncoded
|
|
);
|
|
} __except(EXCEPTION_EXECUTE_HANDLER) {
|
|
fResult = FALSE;
|
|
*pcbEncoded = 0;
|
|
SetLastError(GetExceptionCode());
|
|
}
|
|
if (!fResult || 0 == *pcbEncoded)
|
|
goto CommonReturn;
|
|
|
|
pfnAlloc = PkiGetEncodeAllocFunction(pEncodePara);
|
|
if (NULL == (pbEncoded = (BYTE *) pfnAlloc(*pcbEncoded)))
|
|
goto OutOfMemory;
|
|
} else
|
|
pbEncoded = (BYTE *) pvEncoded;
|
|
|
|
__try {
|
|
fResult = ((PFN_ENCODE_FUNC) pvFuncAddr)(
|
|
dwCertEncodingType,
|
|
lpszStructType,
|
|
pvStructInfo,
|
|
pbEncoded,
|
|
pcbEncoded
|
|
);
|
|
} __except(EXCEPTION_EXECUTE_HANDLER) {
|
|
fResult = FALSE;
|
|
*pcbEncoded = 0;
|
|
SetLastError(GetExceptionCode());
|
|
}
|
|
|
|
#ifdef DEBUG_CRYPT_ASN1_MASTER
|
|
if (pvOssAsn1FuncAddr && fResult && pbEncoded) {
|
|
BOOL fOssAsn1Result;
|
|
BYTE *pbOssAsn1 = NULL;
|
|
DWORD cbOssAsn1;
|
|
|
|
cbOssAsn1 = *pcbEncoded;
|
|
pbOssAsn1 = (BYTE *) PkiNonzeroAlloc(cbOssAsn1);
|
|
if (NULL == pbOssAsn1)
|
|
fOssAsn1Result = FALSE;
|
|
else
|
|
fOssAsn1Result = ((PFN_ENCODE_FUNC) pvOssAsn1FuncAddr)(
|
|
dwCertEncodingType,
|
|
lpszStructType,
|
|
pvStructInfo,
|
|
pbOssAsn1,
|
|
&cbOssAsn1
|
|
);
|
|
|
|
if (!fOssAsn1Result) {
|
|
int id;
|
|
|
|
id = MessageBoxA(
|
|
NULL, // hwndOwner
|
|
"OssCryptAsn1 encode failed. Select Cancel to stop future OssCryptAsn1 encodes",
|
|
"CheckCryptEncodeDecodeAsn1",
|
|
MB_TOPMOST | MB_OKCANCEL | MB_ICONQUESTION |
|
|
MB_SERVICE_NOTIFICATION
|
|
);
|
|
if (IDCANCEL == id)
|
|
iDebugCryptAsn1Flags = 0;
|
|
} else if (*pcbEncoded != cbOssAsn1 ||
|
|
0 != memcmp(pbEncoded, pbOssAsn1, cbOssAsn1)) {
|
|
int id;
|
|
|
|
WriteDERToFile("msasn1.der", pbEncoded, *pcbEncoded);
|
|
WriteDERToFile("ossasn1.der", pbOssAsn1, cbOssAsn1);
|
|
|
|
id = MessageBoxA(
|
|
NULL, // hwndOwner
|
|
"OssCryptAsn1 encode compare failed. Check ossasn1.der and msasn1.der. Select Cancel to stop future OssCryptAsn1 encodes",
|
|
"CheckCryptEncodeDecodeAsn1",
|
|
MB_TOPMOST | MB_OKCANCEL | MB_ICONQUESTION |
|
|
MB_SERVICE_NOTIFICATION
|
|
);
|
|
if (IDCANCEL == id)
|
|
iDebugCryptAsn1Flags = 0;
|
|
}
|
|
|
|
PkiFree(pbOssAsn1);
|
|
}
|
|
#endif // DEBUG_CRYPT_ASN1_MASTER
|
|
|
|
if (dwFlags & CRYPT_ENCODE_ALLOC_FLAG) {
|
|
if (fResult)
|
|
*((BYTE **) pvEncoded) = pbEncoded;
|
|
else {
|
|
PFN_CRYPT_FREE pfnFree;
|
|
pfnFree = PkiGetEncodeFreeFunction(pEncodePara);
|
|
pfnFree(pbEncoded);
|
|
}
|
|
}
|
|
}
|
|
|
|
CommonReturn:
|
|
if (hFuncAddr)
|
|
CryptFreeOIDFunctionAddress(hFuncAddr, 0);
|
|
#ifdef DEBUG_CRYPT_ASN1_MASTER
|
|
if (hOssAsn1FuncAddr)
|
|
CryptFreeOIDFunctionAddress(hOssAsn1FuncAddr, 0);
|
|
#endif // DEBUG_CRYPT_ASN1_MASTER
|
|
|
|
return fResult;
|
|
ErrorReturn:
|
|
*pcbEncoded = 0;
|
|
fResult = FALSE;
|
|
goto CommonReturn;
|
|
SET_ERROR(InvalidFlags, E_INVALIDARG)
|
|
TRACE_ERROR(NoEncodeFunction)
|
|
SET_ERROR(OutOfMemory, E_OUTOFMEMORY)
|
|
}
|
|
|
|
BOOL
|
|
WINAPI
|
|
CryptEncodeObject(
|
|
IN DWORD dwCertEncodingType,
|
|
IN LPCSTR lpszStructType,
|
|
IN const void *pvStructInfo,
|
|
OUT OPTIONAL BYTE *pbEncoded,
|
|
IN OUT DWORD *pcbEncoded
|
|
)
|
|
{
|
|
return CryptEncodeObjectEx(
|
|
dwCertEncodingType,
|
|
lpszStructType,
|
|
pvStructInfo,
|
|
0, // dwFlags
|
|
NULL, // pEncodePara
|
|
pbEncoded,
|
|
pcbEncoded
|
|
);
|
|
}
|
|
|
|
|
|
//+-------------------------------------------------------------------------
|
|
// Decode the specified data structure according to the certificate
|
|
// encoding type.
|
|
//--------------------------------------------------------------------------
|
|
BOOL
|
|
WINAPI
|
|
CryptDecodeObjectEx(
|
|
IN DWORD dwCertEncodingType,
|
|
IN LPCSTR lpszStructType,
|
|
IN const BYTE *pbEncoded,
|
|
IN DWORD cbEncoded,
|
|
IN DWORD dwFlags,
|
|
IN OPTIONAL PCRYPT_DECODE_PARA pDecodePara,
|
|
OUT OPTIONAL void *pvStructInfo,
|
|
IN OUT DWORD *pcbStructInfo
|
|
)
|
|
{
|
|
BOOL fResult;
|
|
void *pvFuncAddr;
|
|
HCRYPTOIDFUNCADDR hFuncAddr = NULL;
|
|
|
|
#ifdef DEBUG_CRYPT_ASN1_MASTER
|
|
int iOssAsn1Flags;
|
|
LPSTR lpszOssAsn1StructType = NULL;
|
|
char szOssOID[128];
|
|
HCRYPTOIDFUNCADDR hOssAsn1FuncAddr = NULL;
|
|
void *pvOssAsn1FuncAddr = NULL;
|
|
|
|
iOssAsn1Flags = GetDebugCryptAsn1Flags() &
|
|
DEBUG_OSS_CRYPT_ASN1_DECODE_FLAG;
|
|
if (iOssAsn1Flags) {
|
|
if (0xFFFF < (DWORD_PTR) lpszStructType) {
|
|
if ((DWORD) strlen(lpszStructType) <
|
|
(sizeof(szOssOID) - strlen(OSS_OID_PREFIX) - 1)) {
|
|
strcpy(szOssOID, OSS_OID_PREFIX);
|
|
strcat(szOssOID, lpszStructType);
|
|
lpszOssAsn1StructType = szOssOID;
|
|
}
|
|
} else
|
|
lpszOssAsn1StructType = (LPSTR) lpszStructType + OSS_OID_OFFSET;
|
|
|
|
if (lpszOssAsn1StructType) {
|
|
if (!CryptGetOIDFunctionAddress(
|
|
hX509DecodeExFuncSet,
|
|
dwCertEncodingType,
|
|
lpszOssAsn1StructType,
|
|
0, // dwFlags
|
|
&pvOssAsn1FuncAddr,
|
|
&hOssAsn1FuncAddr
|
|
))
|
|
pvOssAsn1FuncAddr = NULL;
|
|
}
|
|
}
|
|
|
|
if (pvOssAsn1FuncAddr) {
|
|
fResult = ((PFN_DECODE_EX_FUNC) pvOssAsn1FuncAddr)(
|
|
dwCertEncodingType,
|
|
lpszStructType,
|
|
pbEncoded,
|
|
cbEncoded,
|
|
dwFlags,
|
|
pDecodePara,
|
|
pvStructInfo,
|
|
pcbStructInfo
|
|
);
|
|
} else
|
|
#endif // DEBUG_CRYPT_ASN1_MASTER
|
|
if (CryptGetOIDFunctionAddress(
|
|
hX509DecodeExFuncSet,
|
|
dwCertEncodingType,
|
|
lpszStructType,
|
|
0, // dwFlags
|
|
&pvFuncAddr,
|
|
&hFuncAddr)) {
|
|
__try {
|
|
fResult = ((PFN_DECODE_EX_FUNC) pvFuncAddr)(
|
|
dwCertEncodingType,
|
|
lpszStructType,
|
|
pbEncoded,
|
|
cbEncoded,
|
|
dwFlags,
|
|
pDecodePara,
|
|
pvStructInfo,
|
|
pcbStructInfo
|
|
);
|
|
} __except(EXCEPTION_EXECUTE_HANDLER) {
|
|
fResult = FALSE;
|
|
*pcbStructInfo = 0;
|
|
SetLastError(GetExceptionCode());
|
|
}
|
|
} else {
|
|
void *pv;
|
|
|
|
#ifdef DEBUG_CRYPT_ASN1_MASTER
|
|
if (lpszOssAsn1StructType) {
|
|
if (!CryptGetOIDFunctionAddress(
|
|
hX509DecodeFuncSet,
|
|
dwCertEncodingType,
|
|
lpszOssAsn1StructType,
|
|
0, // dwFlags
|
|
&pvOssAsn1FuncAddr,
|
|
&hOssAsn1FuncAddr
|
|
))
|
|
pvOssAsn1FuncAddr = NULL;
|
|
}
|
|
#endif // DEBUG_CRYPT_ASN1_MASTER
|
|
|
|
if (dwFlags & CRYPT_DECODE_ALLOC_FLAG)
|
|
*((void **) pvStructInfo) = NULL;
|
|
|
|
#ifdef DEBUG_CRYPT_ASN1_MASTER
|
|
if (pvOssAsn1FuncAddr) {
|
|
pvFuncAddr = pvOssAsn1FuncAddr;
|
|
pvOssAsn1FuncAddr = NULL;
|
|
hFuncAddr = hOssAsn1FuncAddr;
|
|
hOssAsn1FuncAddr = NULL;
|
|
} else
|
|
#endif // DEBUG_CRYPT_ASN1_MASTER
|
|
|
|
if (!CryptGetOIDFunctionAddress(
|
|
hX509DecodeFuncSet,
|
|
dwCertEncodingType,
|
|
lpszStructType,
|
|
0, // dwFlags
|
|
&pvFuncAddr,
|
|
&hFuncAddr))
|
|
goto NoDecodeFunction;
|
|
if (dwFlags & CRYPT_DECODE_ALLOC_FLAG) {
|
|
PFN_CRYPT_ALLOC pfnAlloc;
|
|
|
|
*pcbStructInfo = 0;
|
|
__try {
|
|
fResult = ((PFN_DECODE_FUNC) pvFuncAddr)(
|
|
dwCertEncodingType,
|
|
lpszStructType,
|
|
pbEncoded,
|
|
cbEncoded,
|
|
dwFlags & ~CRYPT_DECODE_ALLOC_FLAG,
|
|
NULL,
|
|
pcbStructInfo
|
|
);
|
|
} __except(EXCEPTION_EXECUTE_HANDLER) {
|
|
fResult = FALSE;
|
|
*pcbStructInfo = 0;
|
|
SetLastError(GetExceptionCode());
|
|
}
|
|
if (!fResult || 0 == *pcbStructInfo)
|
|
goto CommonReturn;
|
|
|
|
pfnAlloc = PkiGetDecodeAllocFunction(pDecodePara);
|
|
if (NULL == (pv = pfnAlloc(*pcbStructInfo)))
|
|
goto OutOfMemory;
|
|
} else
|
|
pv = pvStructInfo;
|
|
|
|
__try {
|
|
fResult = ((PFN_DECODE_FUNC) pvFuncAddr)(
|
|
dwCertEncodingType,
|
|
lpszStructType,
|
|
pbEncoded,
|
|
cbEncoded,
|
|
dwFlags & ~CRYPT_DECODE_ALLOC_FLAG,
|
|
pv,
|
|
pcbStructInfo
|
|
);
|
|
} __except(EXCEPTION_EXECUTE_HANDLER) {
|
|
fResult = FALSE;
|
|
*pcbStructInfo = 0;
|
|
SetLastError(GetExceptionCode());
|
|
}
|
|
if (dwFlags & CRYPT_DECODE_ALLOC_FLAG) {
|
|
if (fResult)
|
|
*((void **) pvStructInfo) = pv;
|
|
else {
|
|
PFN_CRYPT_FREE pfnFree;
|
|
pfnFree = PkiGetDecodeFreeFunction(pDecodePara);
|
|
pfnFree(pv);
|
|
}
|
|
}
|
|
}
|
|
|
|
CommonReturn:
|
|
if (hFuncAddr)
|
|
CryptFreeOIDFunctionAddress(hFuncAddr, 0);
|
|
#ifdef DEBUG_CRYPT_ASN1_MASTER
|
|
if (hOssAsn1FuncAddr)
|
|
CryptFreeOIDFunctionAddress(hOssAsn1FuncAddr, 0);
|
|
#endif // DEBUG_CRYPT_ASN1_MASTER
|
|
return fResult;
|
|
ErrorReturn:
|
|
*pcbStructInfo = 0;
|
|
fResult = FALSE;
|
|
goto CommonReturn;
|
|
TRACE_ERROR(NoDecodeFunction)
|
|
SET_ERROR(OutOfMemory, E_OUTOFMEMORY)
|
|
}
|
|
|
|
|
|
BOOL
|
|
WINAPI
|
|
CryptDecodeObject(
|
|
IN DWORD dwCertEncodingType,
|
|
IN LPCSTR lpszStructType,
|
|
IN const BYTE *pbEncoded,
|
|
IN DWORD cbEncoded,
|
|
IN DWORD dwFlags,
|
|
OUT OPTIONAL void *pvStructInfo,
|
|
IN OUT DWORD *pcbStructInfo
|
|
)
|
|
{
|
|
return CryptDecodeObjectEx(
|
|
dwCertEncodingType,
|
|
lpszStructType,
|
|
pbEncoded,
|
|
cbEncoded,
|
|
dwFlags,
|
|
NULL, // pDecodePara
|
|
pvStructInfo,
|
|
pcbStructInfo
|
|
);
|
|
}
|
|
|
|
//+-------------------------------------------------------------------------
|
|
// Encode an ASN1 formatted info structure
|
|
//
|
|
// Called by the Asn1X509*Encode() functions.
|
|
//--------------------------------------------------------------------------
|
|
static BOOL Asn1InfoEncodeEx(
|
|
IN int pdunum,
|
|
IN void *pvAsn1Info,
|
|
IN DWORD dwFlags,
|
|
IN OPTIONAL PCRYPT_ENCODE_PARA pEncodePara,
|
|
OUT OPTIONAL void *pvEncoded,
|
|
IN OUT DWORD *pcbEncoded
|
|
)
|
|
{
|
|
return PkiAsn1EncodeInfoEx(
|
|
GetEncoder(),
|
|
pdunum,
|
|
pvAsn1Info,
|
|
dwFlags,
|
|
pEncodePara,
|
|
pvEncoded,
|
|
pcbEncoded);
|
|
}
|
|
|
|
//+-------------------------------------------------------------------------
|
|
// Decode into an allocated, ASN1 formatted info structure
|
|
//
|
|
// Called by the Asn1X509*Decode() functions.
|
|
//--------------------------------------------------------------------------
|
|
static BOOL Asn1InfoDecodeAndAlloc(
|
|
IN int pdunum,
|
|
IN const BYTE *pbEncoded,
|
|
IN DWORD cbEncoded,
|
|
OUT void **ppvAsn1Info
|
|
)
|
|
{
|
|
return PkiAsn1DecodeAndAllocInfo(
|
|
GetDecoder(),
|
|
pdunum,
|
|
pbEncoded,
|
|
cbEncoded,
|
|
ppvAsn1Info);
|
|
}
|
|
|
|
//+-------------------------------------------------------------------------
|
|
// Free an allocated, ASN1 formatted info structure
|
|
//
|
|
// Called by the Asn1X509*Decode() functions.
|
|
//--------------------------------------------------------------------------
|
|
static void Asn1InfoFree(
|
|
IN int pdunum,
|
|
IN void *pAsn1Info
|
|
)
|
|
{
|
|
if (pAsn1Info) {
|
|
DWORD dwErr = GetLastError();
|
|
|
|
// TlsGetValue globbers LastError
|
|
PkiAsn1FreeInfo(GetDecoder(), pdunum, pAsn1Info);
|
|
|
|
SetLastError(dwErr);
|
|
}
|
|
}
|
|
|
|
//+-------------------------------------------------------------------------
|
|
// Decode into an ASN1 formatted info structure. Call the callback
|
|
// function to convert into the 'C' data structure. If
|
|
// CRYPT_DECODE_ALLOC_FLAG is set, call the callback twice. First,
|
|
// to get the length of the 'C' data structure. Then after allocating,
|
|
// call again to update the 'C' data structure.
|
|
//
|
|
// Called by the Asn1X509*Decode() functions.
|
|
//--------------------------------------------------------------------------
|
|
static BOOL Asn1InfoDecodeAndAllocEx(
|
|
IN int pdunum,
|
|
IN const BYTE *pbEncoded,
|
|
IN DWORD cbEncoded,
|
|
IN DWORD dwFlags,
|
|
IN OPTIONAL PCRYPT_DECODE_PARA pDecodePara,
|
|
IN PFN_PKI_ASN1_DECODE_EX_CALLBACK pfnDecodeExCallback,
|
|
OUT OPTIONAL void *pvStructInfo,
|
|
IN OUT DWORD *pcbStructInfo
|
|
)
|
|
{
|
|
return PkiAsn1DecodeAndAllocInfoEx(
|
|
GetDecoder(),
|
|
pdunum,
|
|
pbEncoded,
|
|
cbEncoded,
|
|
dwFlags,
|
|
pDecodePara,
|
|
pfnDecodeExCallback,
|
|
pvStructInfo,
|
|
pcbStructInfo
|
|
);
|
|
}
|
|
|
|
//+-------------------------------------------------------------------------
|
|
// ASN1 X509 v3 ASN.1 Set / Get functions
|
|
//
|
|
// Called by the ASN1 X509 encode/decode functions.
|
|
//
|
|
// Assumption: all types are UNBOUNDED.
|
|
//
|
|
// The Get functions decrement *plRemainExtra and advance
|
|
// *ppbExtra. When *plRemainExtra becomes negative, the functions continue
|
|
// with the length calculation but stop doing any copies.
|
|
// The functions don't return an error for a negative *plRemainExtra.
|
|
//--------------------------------------------------------------------------
|
|
|
|
|
|
//+-------------------------------------------------------------------------
|
|
// Set/Get Encoded Object Identifier string
|
|
//--------------------------------------------------------------------------
|
|
#ifdef OSS_CRYPT_ASN1
|
|
#define Asn1X509SetEncodedObjId(pszObjId, pAsn1) \
|
|
I_CryptSetEncodedOID(pszObjId, (OssEncodedOID *) (pAsn1))
|
|
|
|
#define Asn1X509GetEncodedObjId(pAsn1, dwFlags, \
|
|
ppszObjId, ppbExtra, plRemainExtra) \
|
|
I_CryptGetEncodedOID((OssEncodedOID *) (pAsn1), dwFlags, \
|
|
ppszObjId, ppbExtra, plRemainExtra)
|
|
|
|
#else
|
|
|
|
#define Asn1X509SetEncodedObjId(pszObjId, pAsn1) \
|
|
I_CryptSetEncodedOID(pszObjId, pAsn1)
|
|
|
|
#define Asn1X509GetEncodedObjId(pAsn1, dwFlags, \
|
|
ppszObjId, ppbExtra, plRemainExtra) \
|
|
I_CryptGetEncodedOID(pAsn1, dwFlags, \
|
|
ppszObjId, ppbExtra, plRemainExtra)
|
|
|
|
#endif // OSS_CRYPT_ASN1
|
|
|
|
//+-------------------------------------------------------------------------
|
|
// Set/Get CRYPT_DATA_BLOB (Octet String)
|
|
//--------------------------------------------------------------------------
|
|
inline void Asn1X509SetOctetString(
|
|
IN PCRYPT_DATA_BLOB pInfo,
|
|
OUT OCTETSTRING *pAsn1
|
|
)
|
|
{
|
|
pAsn1->value = pInfo->pbData;
|
|
pAsn1->length = pInfo->cbData;
|
|
}
|
|
inline void Asn1X509GetOctetString(
|
|
IN OCTETSTRING *pAsn1,
|
|
IN DWORD dwFlags,
|
|
OUT PCRYPT_DATA_BLOB pInfo,
|
|
IN OUT BYTE **ppbExtra,
|
|
IN OUT LONG *plRemainExtra
|
|
)
|
|
{
|
|
PkiAsn1GetOctetString(pAsn1->length, pAsn1->value, dwFlags,
|
|
pInfo, ppbExtra, plRemainExtra);
|
|
}
|
|
|
|
//+-------------------------------------------------------------------------
|
|
// Set/Free/Get CRYPT_INTEGER_BLOB
|
|
//--------------------------------------------------------------------------
|
|
inline BOOL Asn1X509SetHugeInteger(
|
|
IN PCRYPT_INTEGER_BLOB pInfo,
|
|
OUT HUGEINTEGER *pAsn1
|
|
)
|
|
{
|
|
return PkiAsn1SetHugeInteger(pInfo, &pAsn1->length, &pAsn1->value);
|
|
}
|
|
inline void Asn1X509FreeHugeInteger(
|
|
IN HUGEINTEGER *pAsn1
|
|
)
|
|
{
|
|
PkiAsn1FreeHugeInteger(pAsn1->value);
|
|
pAsn1->value = NULL;
|
|
pAsn1->length = 0;
|
|
}
|
|
inline void Asn1X509GetHugeInteger(
|
|
IN HUGEINTEGER *pAsn1,
|
|
IN DWORD dwFlags,
|
|
OUT PCRYPT_INTEGER_BLOB pInfo,
|
|
IN OUT BYTE **ppbExtra,
|
|
IN OUT LONG *plRemainExtra
|
|
)
|
|
{
|
|
PkiAsn1GetHugeInteger(pAsn1->length, pAsn1->value, dwFlags,
|
|
pInfo, ppbExtra, plRemainExtra);
|
|
}
|
|
|
|
//+-------------------------------------------------------------------------
|
|
// Set/Free/Get CRYPT_UINT_BLOB
|
|
//--------------------------------------------------------------------------
|
|
inline BOOL Asn1X509SetHugeUINT(
|
|
IN PCRYPT_UINT_BLOB pInfo,
|
|
OUT HUGEINTEGER *pAsn1
|
|
)
|
|
{
|
|
return PkiAsn1SetHugeUINT(pInfo, &pAsn1->length, &pAsn1->value);
|
|
}
|
|
|
|
#define Asn1X509FreeHugeUINT Asn1X509FreeHugeInteger
|
|
|
|
inline void Asn1X509GetHugeUINT(
|
|
IN HUGEINTEGER *pAsn1,
|
|
IN DWORD dwFlags,
|
|
OUT PCRYPT_UINT_BLOB pInfo,
|
|
IN OUT BYTE **ppbExtra,
|
|
IN OUT LONG *plRemainExtra
|
|
)
|
|
{
|
|
PkiAsn1GetHugeUINT(pAsn1->length, pAsn1->value, dwFlags,
|
|
pInfo, ppbExtra, plRemainExtra);
|
|
}
|
|
|
|
//+-------------------------------------------------------------------------
|
|
// Set/Get CRYPT_BIT_BLOB
|
|
//--------------------------------------------------------------------------
|
|
inline void Asn1X509SetBit(
|
|
IN PCRYPT_BIT_BLOB pInfo,
|
|
OUT BITSTRING *pAsn1
|
|
)
|
|
{
|
|
PkiAsn1SetBitString(pInfo, &pAsn1->length, &pAsn1->value);
|
|
}
|
|
inline void Asn1X509GetBit(
|
|
IN BITSTRING *pAsn1,
|
|
IN DWORD dwFlags,
|
|
OUT PCRYPT_BIT_BLOB pInfo,
|
|
IN OUT BYTE **ppbExtra,
|
|
IN OUT LONG *plRemainExtra
|
|
)
|
|
{
|
|
PkiAsn1GetBitString(pAsn1->length, pAsn1->value, dwFlags,
|
|
pInfo, ppbExtra, plRemainExtra);
|
|
}
|
|
|
|
inline void Asn1X509SetBitWithoutTrailingZeroes(
|
|
IN PCRYPT_BIT_BLOB pInfo,
|
|
OUT BITSTRING *pAsn1
|
|
)
|
|
{
|
|
PkiAsn1SetBitStringWithoutTrailingZeroes(
|
|
pInfo, &pAsn1->length, &pAsn1->value);
|
|
}
|
|
|
|
|
|
//+-------------------------------------------------------------------------
|
|
// Set/Get LPSTR (IA5 String)
|
|
//--------------------------------------------------------------------------
|
|
inline void Asn1X509SetIA5(
|
|
IN LPSTR psz,
|
|
OUT IA5STRING *pAsn1
|
|
)
|
|
{
|
|
pAsn1->value = psz;
|
|
pAsn1->length = strlen(psz);
|
|
}
|
|
inline void Asn1X509GetIA5(
|
|
IN IA5STRING *pAsn1,
|
|
IN DWORD dwFlags,
|
|
OUT LPSTR *ppsz,
|
|
IN OUT BYTE **ppbExtra,
|
|
IN OUT LONG *plRemainExtra
|
|
)
|
|
{
|
|
PkiAsn1GetIA5String(pAsn1->length, pAsn1->value, dwFlags,
|
|
ppsz, ppbExtra, plRemainExtra);
|
|
}
|
|
|
|
//+-------------------------------------------------------------------------
|
|
// Set/Free/Get Unicode mapped to IA5 String
|
|
//--------------------------------------------------------------------------
|
|
BOOL Asn1X509SetUnicodeConvertedToIA5(
|
|
IN LPWSTR pwsz,
|
|
OUT IA5STRING *pAsn1,
|
|
IN DWORD dwIndex,
|
|
OUT DWORD *pdwErrLocation
|
|
)
|
|
{
|
|
BOOL fResult;
|
|
fResult = PkiAsn1SetUnicodeConvertedToIA5String(pwsz,
|
|
&pAsn1->length, &pAsn1->value);
|
|
if (!fResult && (DWORD) CRYPT_E_INVALID_IA5_STRING == GetLastError())
|
|
*pdwErrLocation = (dwIndex << 16) | pAsn1->length;
|
|
else
|
|
*pdwErrLocation = 0;
|
|
return fResult;
|
|
}
|
|
inline void Asn1X509FreeUnicodeConvertedToIA5(IN IA5STRING *pAsn1)
|
|
{
|
|
PkiAsn1FreeUnicodeConvertedToIA5String(pAsn1->value);
|
|
pAsn1->value = NULL;
|
|
}
|
|
inline void Asn1X509GetIA5ConvertedToUnicode(
|
|
IN IA5STRING *pAsn1,
|
|
IN DWORD dwFlags,
|
|
OUT LPWSTR *ppwsz,
|
|
IN OUT BYTE **ppbExtra,
|
|
IN OUT LONG *plRemainExtra
|
|
)
|
|
{
|
|
PkiAsn1GetIA5StringConvertedToUnicode(pAsn1->length, pAsn1->value, dwFlags,
|
|
ppwsz, ppbExtra, plRemainExtra);
|
|
}
|
|
|
|
//+-------------------------------------------------------------------------
|
|
// Set/Get LPWSTR (BMP String)
|
|
//--------------------------------------------------------------------------
|
|
inline void Asn1X509SetBMP(
|
|
IN LPWSTR pwsz,
|
|
OUT BMPSTRING *pAsn1
|
|
)
|
|
{
|
|
pAsn1->value = pwsz;
|
|
pAsn1->length = wcslen(pwsz);
|
|
}
|
|
inline void Asn1X509GetBMP(
|
|
IN BMPSTRING *pAsn1,
|
|
IN DWORD dwFlags,
|
|
OUT LPWSTR *ppwsz,
|
|
IN OUT BYTE **ppbExtra,
|
|
IN OUT LONG *plRemainExtra
|
|
)
|
|
{
|
|
PkiAsn1GetBMPString(pAsn1->length, pAsn1->value, dwFlags,
|
|
ppwsz, ppbExtra, plRemainExtra);
|
|
}
|
|
|
|
|
|
//+-------------------------------------------------------------------------
|
|
// Set/Get "Any" DER BLOB
|
|
//--------------------------------------------------------------------------
|
|
inline void Asn1X509SetAny(
|
|
IN PCRYPT_OBJID_BLOB pInfo,
|
|
OUT NOCOPYANY *pAsn1
|
|
)
|
|
{
|
|
PkiAsn1SetAny(pInfo, pAsn1);
|
|
}
|
|
inline void Asn1X509GetAny(
|
|
IN NOCOPYANY *pAsn1,
|
|
IN DWORD dwFlags,
|
|
OUT PCRYPT_OBJID_BLOB pInfo,
|
|
IN OUT BYTE **ppbExtra,
|
|
IN OUT LONG *plRemainExtra
|
|
)
|
|
{
|
|
PkiAsn1GetAny(pAsn1, dwFlags, pInfo, ppbExtra, plRemainExtra);
|
|
}
|
|
|
|
//+-------------------------------------------------------------------------
|
|
// Set/Get CRYPT_ALGORITHM_IDENTIFIER
|
|
//--------------------------------------------------------------------------
|
|
BOOL Asn1X509SetAlgorithm(
|
|
IN PCRYPT_ALGORITHM_IDENTIFIER pInfo,
|
|
OUT AlgorithmIdentifier *pAsn1,
|
|
IN DWORD dwGroupId = 0
|
|
)
|
|
{
|
|
memset(pAsn1, 0, sizeof(*pAsn1));
|
|
if (pInfo->pszObjId) {
|
|
if (!Asn1X509SetEncodedObjId(pInfo->pszObjId, &pAsn1->algorithm))
|
|
return FALSE;
|
|
|
|
if (pInfo->Parameters.cbData) {
|
|
Asn1X509SetAny(&pInfo->Parameters, &pAsn1->parameters);
|
|
pAsn1->bit_mask |= parameters_present;
|
|
} else {
|
|
if (dwGroupId) {
|
|
// For public key or signature algorithms, check if
|
|
// NO NULL parameters.
|
|
|
|
PCCRYPT_OID_INFO pOIDInfo;
|
|
DWORD dwFlags = 0;
|
|
|
|
switch (dwGroupId) {
|
|
case CRYPT_PUBKEY_ALG_OID_GROUP_ID:
|
|
if (pOIDInfo = CryptFindOIDInfo(
|
|
CRYPT_OID_INFO_OID_KEY,
|
|
pInfo->pszObjId,
|
|
CRYPT_PUBKEY_ALG_OID_GROUP_ID)) {
|
|
if (1 <= pOIDInfo->ExtraInfo.cbData /
|
|
sizeof(DWORD)) {
|
|
DWORD *pdwExtra = (DWORD *)
|
|
pOIDInfo->ExtraInfo.pbData;
|
|
dwFlags = pdwExtra[0];
|
|
}
|
|
}
|
|
break;
|
|
case CRYPT_SIGN_ALG_OID_GROUP_ID:
|
|
if (pOIDInfo = CryptFindOIDInfo(
|
|
CRYPT_OID_INFO_OID_KEY,
|
|
pInfo->pszObjId,
|
|
CRYPT_SIGN_ALG_OID_GROUP_ID)) {
|
|
if (2 <= pOIDInfo->ExtraInfo.cbData /
|
|
sizeof(DWORD)) {
|
|
DWORD *pdwExtra = (DWORD *)
|
|
pOIDInfo->ExtraInfo.pbData;
|
|
dwFlags = pdwExtra[1];
|
|
}
|
|
}
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
|
|
if (dwFlags & CRYPT_OID_NO_NULL_ALGORITHM_PARA_FLAG)
|
|
return TRUE;
|
|
}
|
|
|
|
// Per PKCS #1: default to the ASN.1 type NULL.
|
|
Asn1X509SetAny((PCRYPT_OBJID_BLOB) &NullDerBlob, &pAsn1->parameters);
|
|
pAsn1->bit_mask |= parameters_present;
|
|
}
|
|
}
|
|
return TRUE;
|
|
}
|
|
|
|
void Asn1X509GetAlgorithm(
|
|
IN AlgorithmIdentifier *pAsn1,
|
|
IN DWORD dwFlags,
|
|
OUT PCRYPT_ALGORITHM_IDENTIFIER pInfo,
|
|
IN OUT BYTE **ppbExtra,
|
|
IN OUT LONG *plRemainExtra
|
|
)
|
|
{
|
|
if (*plRemainExtra >= 0)
|
|
memset(pInfo, 0, sizeof(*pInfo));
|
|
Asn1X509GetEncodedObjId(&pAsn1->algorithm, dwFlags, &pInfo->pszObjId,
|
|
ppbExtra, plRemainExtra);
|
|
if (pAsn1->bit_mask & parameters_present)
|
|
Asn1X509GetAny(&pAsn1->parameters, dwFlags, &pInfo->Parameters,
|
|
ppbExtra, plRemainExtra);
|
|
}
|
|
|
|
//+-------------------------------------------------------------------------
|
|
// Set/Get CERT_PUBLIC_KEY_INFO
|
|
//--------------------------------------------------------------------------
|
|
BOOL Asn1X509SetPublicKeyInfo(
|
|
IN PCERT_PUBLIC_KEY_INFO pInfo,
|
|
OUT SubjectPublicKeyInfo *pAsn1
|
|
)
|
|
{
|
|
if (!Asn1X509SetAlgorithm(&pInfo->Algorithm, &pAsn1->algorithm,
|
|
CRYPT_PUBKEY_ALG_OID_GROUP_ID))
|
|
return FALSE;
|
|
Asn1X509SetBit(&pInfo->PublicKey, &pAsn1->subjectPublicKey);
|
|
return TRUE;
|
|
}
|
|
|
|
void Asn1X509GetPublicKeyInfo(
|
|
IN SubjectPublicKeyInfo *pAsn1,
|
|
IN DWORD dwFlags,
|
|
OUT PCERT_PUBLIC_KEY_INFO pInfo,
|
|
IN OUT BYTE **ppbExtra,
|
|
IN OUT LONG *plRemainExtra
|
|
)
|
|
{
|
|
Asn1X509GetAlgorithm(&pAsn1->algorithm, dwFlags, &pInfo->Algorithm,
|
|
ppbExtra, plRemainExtra);
|
|
Asn1X509GetBit(&pAsn1->subjectPublicKey, dwFlags, &pInfo->PublicKey,
|
|
ppbExtra, plRemainExtra);
|
|
}
|
|
|
|
//+-------------------------------------------------------------------------
|
|
// Set/Free/Get Extensions
|
|
//--------------------------------------------------------------------------
|
|
BOOL Asn1X509SetExtensions(
|
|
IN DWORD cExtension,
|
|
IN PCERT_EXTENSION pExtension,
|
|
OUT Extensions *pAsn1
|
|
)
|
|
{
|
|
Extension *pAsn1Ext;
|
|
|
|
pAsn1->value = NULL;
|
|
pAsn1->count = 0;
|
|
if (cExtension == 0)
|
|
return TRUE;
|
|
|
|
pAsn1Ext = (Extension *) PkiZeroAlloc(cExtension * sizeof(Extension));
|
|
if (pAsn1Ext == NULL)
|
|
return FALSE;
|
|
pAsn1->value = pAsn1Ext;
|
|
pAsn1->count = cExtension;
|
|
|
|
for ( ; cExtension > 0; cExtension--, pExtension++, pAsn1Ext++) {
|
|
if (!Asn1X509SetEncodedObjId(pExtension->pszObjId, &pAsn1Ext->extnId))
|
|
return FALSE;
|
|
if (pExtension->fCritical) {
|
|
pAsn1Ext->critical = TRUE;
|
|
pAsn1Ext->bit_mask |= critical_present;
|
|
}
|
|
Asn1X509SetOctetString(&pExtension->Value, &pAsn1Ext->extnValue);
|
|
}
|
|
return TRUE;
|
|
}
|
|
|
|
void Asn1X509FreeExtensions(
|
|
IN Extensions *pAsn1)
|
|
{
|
|
if (pAsn1->value) {
|
|
PkiFree(pAsn1->value);
|
|
pAsn1->value = NULL;
|
|
}
|
|
pAsn1->count = 0;
|
|
}
|
|
|
|
void Asn1X509GetExtensions(
|
|
IN Extensions *pAsn1,
|
|
IN DWORD dwFlags,
|
|
OUT DWORD *pcExtension,
|
|
OUT PCERT_EXTENSION *ppExtension,
|
|
IN OUT BYTE **ppbExtra,
|
|
IN OUT LONG *plRemainExtra
|
|
)
|
|
{
|
|
LONG lRemainExtra = *plRemainExtra;
|
|
BYTE *pbExtra = *ppbExtra;
|
|
LONG lAlignExtra;
|
|
|
|
DWORD cExt;
|
|
Extension *pAsn1Ext;
|
|
PCERT_EXTENSION pGetExt;
|
|
|
|
cExt = pAsn1->count;
|
|
lAlignExtra = INFO_LEN_ALIGN(cExt * sizeof(CERT_EXTENSION));
|
|
lRemainExtra -= lAlignExtra;
|
|
if (lRemainExtra >= 0) {
|
|
*pcExtension = cExt;
|
|
pGetExt = (PCERT_EXTENSION) pbExtra;
|
|
*ppExtension = pGetExt;
|
|
pbExtra += lAlignExtra;
|
|
} else
|
|
pGetExt = NULL;
|
|
|
|
pAsn1Ext = pAsn1->value;
|
|
for ( ; cExt > 0; cExt--, pAsn1Ext++, pGetExt++) {
|
|
Asn1X509GetEncodedObjId(&pAsn1Ext->extnId, dwFlags, &pGetExt->pszObjId,
|
|
&pbExtra, &lRemainExtra);
|
|
if (lRemainExtra >= 0) {
|
|
pGetExt->fCritical = FALSE;
|
|
if (pAsn1Ext->bit_mask & critical_present)
|
|
pGetExt->fCritical = (BOOLEAN) pAsn1Ext->critical;
|
|
}
|
|
|
|
Asn1X509GetOctetString(&pAsn1Ext->extnValue, dwFlags, &pGetExt->Value,
|
|
&pbExtra, &lRemainExtra);
|
|
}
|
|
|
|
*plRemainExtra = lRemainExtra;
|
|
*ppbExtra = pbExtra;
|
|
}
|
|
|
|
//+-------------------------------------------------------------------------
|
|
// Set/Free/Get CRL Entries
|
|
//--------------------------------------------------------------------------
|
|
BOOL Asn1X509SetCrlEntries(
|
|
IN DWORD cEntry,
|
|
IN PCRL_ENTRY pEntry,
|
|
OUT RevokedCertificates *pAsn1
|
|
)
|
|
{
|
|
CRLEntry *pAsn1Entry;
|
|
|
|
pAsn1->value = NULL;
|
|
pAsn1->count = 0;
|
|
if (cEntry == 0)
|
|
return TRUE;
|
|
|
|
pAsn1Entry = (CRLEntry *) PkiZeroAlloc(cEntry * sizeof(CRLEntry));
|
|
if (pAsn1Entry == NULL)
|
|
return FALSE;
|
|
pAsn1->value = pAsn1Entry;
|
|
pAsn1->count = cEntry;
|
|
|
|
for ( ; cEntry > 0; cEntry--, pEntry++, pAsn1Entry++) {
|
|
if (!Asn1X509SetHugeInteger(&pEntry->SerialNumber,
|
|
&pAsn1Entry->userCertificate))
|
|
return FALSE;
|
|
if (!PkiAsn1ToChoiceOfTime(&pEntry->RevocationDate,
|
|
&pAsn1Entry->revocationDate.choice,
|
|
&pAsn1Entry->revocationDate.u.generalTime,
|
|
&pAsn1Entry->revocationDate.u.utcTime
|
|
)) {
|
|
SetLastError((DWORD) CRYPT_E_BAD_ENCODE);
|
|
return FALSE;
|
|
}
|
|
if (pEntry->cExtension) {
|
|
if (!Asn1X509SetExtensions(pEntry->cExtension, pEntry->rgExtension,
|
|
&pAsn1Entry->crlEntryExtensions))
|
|
return FALSE;
|
|
pAsn1Entry->bit_mask |= crlEntryExtensions_present;
|
|
}
|
|
}
|
|
return TRUE;
|
|
}
|
|
|
|
void Asn1X509FreeCrlEntries(
|
|
IN RevokedCertificates *pAsn1)
|
|
{
|
|
if (pAsn1->value) {
|
|
CRLEntry *pAsn1Entry = pAsn1->value;
|
|
DWORD cEntry = pAsn1->count;
|
|
for ( ; cEntry > 0; cEntry--, pAsn1Entry++) {
|
|
Asn1X509FreeHugeInteger(&pAsn1Entry->userCertificate);
|
|
Asn1X509FreeExtensions(&pAsn1Entry->crlEntryExtensions);
|
|
}
|
|
PkiFree(pAsn1->value);
|
|
pAsn1->value = NULL;
|
|
}
|
|
pAsn1->count = 0;
|
|
}
|
|
|
|
BOOL Asn1X509GetCrlEntries(
|
|
IN RevokedCertificates *pAsn1,
|
|
IN DWORD dwFlags,
|
|
OUT DWORD *pcEntry,
|
|
OUT PCRL_ENTRY *ppEntry,
|
|
IN OUT BYTE **ppbExtra,
|
|
IN OUT LONG *plRemainExtra
|
|
)
|
|
{
|
|
LONG lRemainExtra = *plRemainExtra;
|
|
BYTE *pbExtra = *ppbExtra;
|
|
LONG lAlignExtra;
|
|
|
|
DWORD cEntry;
|
|
CRLEntry *pAsn1Entry;
|
|
PCRL_ENTRY pGetEntry;
|
|
|
|
cEntry = pAsn1->count;
|
|
lAlignExtra = INFO_LEN_ALIGN(cEntry * sizeof(CRL_ENTRY));
|
|
lRemainExtra -= lAlignExtra;
|
|
if (lRemainExtra >= 0) {
|
|
*pcEntry = cEntry;
|
|
pGetEntry = (PCRL_ENTRY) pbExtra;
|
|
*ppEntry = pGetEntry;
|
|
pbExtra += lAlignExtra;
|
|
} else
|
|
pGetEntry = NULL;
|
|
|
|
pAsn1Entry = pAsn1->value;
|
|
for ( ; cEntry > 0; cEntry--, pAsn1Entry++, pGetEntry++) {
|
|
Asn1X509GetHugeInteger(&pAsn1Entry->userCertificate, dwFlags,
|
|
&pGetEntry->SerialNumber, &pbExtra, &lRemainExtra);
|
|
|
|
// RevocationDate
|
|
if (lRemainExtra >= 0) {
|
|
if (!PkiAsn1FromChoiceOfTime(pAsn1Entry->revocationDate.choice,
|
|
&pAsn1Entry->revocationDate.u.generalTime,
|
|
&pAsn1Entry->revocationDate.u.utcTime,
|
|
&pGetEntry->RevocationDate)) {
|
|
SetLastError((DWORD) CRYPT_E_BAD_ENCODE);
|
|
return FALSE;
|
|
}
|
|
}
|
|
|
|
// Extensions
|
|
if (pAsn1Entry->bit_mask & crlEntryExtensions_present)
|
|
Asn1X509GetExtensions(&pAsn1Entry->crlEntryExtensions, dwFlags,
|
|
&pGetEntry->cExtension, &pGetEntry->rgExtension,
|
|
&pbExtra, &lRemainExtra);
|
|
else if (lRemainExtra >= 0) {
|
|
pGetEntry->cExtension = 0;
|
|
pGetEntry->rgExtension = NULL;
|
|
}
|
|
}
|
|
|
|
*plRemainExtra = lRemainExtra;
|
|
*ppbExtra = pbExtra;
|
|
return TRUE;
|
|
}
|
|
|
|
#ifndef ASN1_SUPPORTS_UTF8_TAG
|
|
|
|
void inline Asn1X509ReverseCopy(
|
|
OUT BYTE *pbOut,
|
|
IN BYTE *pbInOrg,
|
|
IN DWORD cbIn
|
|
)
|
|
{
|
|
BYTE *pbIn = pbInOrg + cbIn - 1;
|
|
|
|
while (cbIn-- > 0)
|
|
*pbOut++ = *pbIn--;
|
|
}
|
|
|
|
#define MAX_LENGTH_OCTETS 5
|
|
|
|
//+-------------------------------------------------------------------------
|
|
// Copy out the encoding of the length octets for a specified content length.
|
|
//
|
|
// Returns the number of length octets
|
|
//--------------------------------------------------------------------------
|
|
DWORD Asn1X509GetLengthOctets(
|
|
IN DWORD cbContent,
|
|
OUT BYTE rgbLength[MAX_LENGTH_OCTETS]
|
|
)
|
|
{
|
|
DWORD cbLength;
|
|
|
|
if (cbContent < 0x80) {
|
|
rgbLength[0] = (BYTE) cbContent;
|
|
cbLength = 0;
|
|
} else {
|
|
if (cbContent > 0xffffff)
|
|
cbLength = 4;
|
|
else if (cbContent > 0xffff)
|
|
cbLength = 3;
|
|
else if (cbContent > 0xff)
|
|
cbLength = 2;
|
|
else
|
|
cbLength = 1;
|
|
rgbLength[0] = (BYTE) cbLength | 0x80;
|
|
Asn1X509ReverseCopy(rgbLength + 1, (BYTE *) &cbContent, cbLength);
|
|
}
|
|
return cbLength + 1;
|
|
}
|
|
|
|
// Prefix includes:
|
|
// - 1 byte for number of unused bytes in the prefix
|
|
// - 1 byte for the tag
|
|
// - up to 5 bytes for the length octets
|
|
#define MAX_ENCODED_UTF8_PREFIX (1 + 1 + MAX_LENGTH_OCTETS)
|
|
#define UTF8_ASN_TAG 0x0C
|
|
|
|
//+-------------------------------------------------------------------------
|
|
// Allocate and Encode UTF8
|
|
//
|
|
// The returned pbEncoded points to an ASN.1 encoded UTF8 string.
|
|
// pbEncoded points to the UTF8_ASN_TAG, followed by the length octets and
|
|
// then the UTF8 bytes.
|
|
//
|
|
// *(pbEncoded -1) contains the number of unused bytes preceding the encoded
|
|
// UTF8, ie, pbAllocEncoded = pbEncoded - *(pbEncoded -1).
|
|
//--------------------------------------------------------------------------
|
|
BOOL Asn1X509AllocAndEncodeUTF8(
|
|
IN PCERT_RDN_VALUE_BLOB pValue,
|
|
OUT BYTE **ppbEncoded,
|
|
OUT DWORD *pcbEncoded
|
|
)
|
|
{
|
|
BOOL fResult;
|
|
BYTE *pbAllocEncoded = NULL;
|
|
BYTE *pbEncoded;
|
|
DWORD cbEncoded;
|
|
BYTE rgbLength[MAX_LENGTH_OCTETS];
|
|
DWORD cbLength;
|
|
DWORD cbUnusedPrefix;
|
|
int cchUnicode;
|
|
int cchUTF8;
|
|
|
|
cchUnicode = pValue->cbData / sizeof(WCHAR);
|
|
|
|
// In the largest buffer case there are 3 bytes per Unicode character.
|
|
// The encoded UTF8 is preceded with a prefix consisting of a byte
|
|
// indicating the number of unused bytes in the prefix, a byte for the
|
|
// UTF8 tag and up to 5 bytes for the length octets.
|
|
if (NULL == (pbAllocEncoded = (BYTE *) PkiNonzeroAlloc(
|
|
MAX_ENCODED_UTF8_PREFIX + cchUnicode * 3)))
|
|
goto OutOfMemory;
|
|
|
|
if (0 == cchUnicode)
|
|
cchUTF8 = 0;
|
|
else {
|
|
if (0 >= (cchUTF8 = WideCharToUTF8(
|
|
(LPCWSTR) pValue->pbData,
|
|
cchUnicode,
|
|
(LPSTR) (pbAllocEncoded + MAX_ENCODED_UTF8_PREFIX),
|
|
cchUnicode * 3
|
|
)))
|
|
goto WideCharToUTF8Error;
|
|
}
|
|
|
|
cbLength = Asn1X509GetLengthOctets(cchUTF8, rgbLength);
|
|
assert(MAX_ENCODED_UTF8_PREFIX > (1 + cbLength));
|
|
cbUnusedPrefix = MAX_ENCODED_UTF8_PREFIX - (1 + cbLength);
|
|
pbEncoded = pbAllocEncoded + cbUnusedPrefix;
|
|
cbEncoded = 1 + cbLength + cchUTF8;
|
|
*(pbEncoded - 1) = (BYTE) cbUnusedPrefix;
|
|
*(pbEncoded) = UTF8_ASN_TAG;
|
|
memcpy(pbEncoded + 1, rgbLength, cbLength);
|
|
|
|
fResult = TRUE;
|
|
CommonReturn:
|
|
*ppbEncoded = pbEncoded;
|
|
*pcbEncoded = cbEncoded;
|
|
return fResult;
|
|
|
|
ErrorReturn:
|
|
PkiFree(pbAllocEncoded);
|
|
pbEncoded = NULL;
|
|
cbEncoded = 0;
|
|
fResult = FALSE;
|
|
goto CommonReturn;
|
|
TRACE_ERROR(OutOfMemory)
|
|
TRACE_ERROR(WideCharToUTF8Error)
|
|
}
|
|
|
|
//+-------------------------------------------------------------------------
|
|
// Free previously encoded UTF8
|
|
//
|
|
// *(pbEncoded -1) contains the number of unused bytes preceding the encoded
|
|
// UTF8, ie, pbAllocEncoded = pbEncoded - *(pbEncoded -1).
|
|
//--------------------------------------------------------------------------
|
|
void Asn1X509FreeEncodedUTF8(
|
|
IN BYTE *pbEncoded
|
|
)
|
|
{
|
|
if (pbEncoded) {
|
|
BYTE *pbAllocEncoded;
|
|
|
|
assert(MAX_ENCODED_UTF8_PREFIX > *(pbEncoded -1));
|
|
|
|
pbAllocEncoded = pbEncoded - *(pbEncoded - 1);
|
|
PkiFree(pbAllocEncoded);
|
|
}
|
|
}
|
|
|
|
//+-------------------------------------------------------------------------
|
|
// Get UTF8
|
|
//--------------------------------------------------------------------------
|
|
BOOL Asn1X509GetUTF8(
|
|
IN NOCOPYANY *pAsn1,
|
|
IN DWORD dwFlags,
|
|
OUT DWORD *pdwValueType,
|
|
OUT PCERT_RDN_VALUE_BLOB pValue,
|
|
IN OUT BYTE **ppbExtra,
|
|
IN OUT LONG *plRemainExtra
|
|
)
|
|
{
|
|
BOOL fResult;
|
|
const BYTE *pbEncoded = (const BYTE *) pAsn1->encoded;
|
|
DWORD cbEncoded = pAsn1->length;
|
|
const BYTE *pbContent;
|
|
DWORD cbContent;
|
|
int cchUnicode;
|
|
LPWSTR pwszUnicode = NULL;
|
|
LONG lAlignExtra;
|
|
LONG lData;
|
|
|
|
|
|
if (0 == cbEncoded || UTF8_ASN_TAG != *pbEncoded)
|
|
goto InvalidUTF8Tag;
|
|
|
|
if (0 >= Asn1UtilExtractContent(
|
|
pbEncoded,
|
|
cbEncoded,
|
|
&cbContent,
|
|
&pbContent
|
|
))
|
|
goto InvalidUTF8Header;
|
|
|
|
if (0 == cbContent)
|
|
cchUnicode = 0;
|
|
else {
|
|
if (pbContent + cbContent > pbEncoded + cbEncoded)
|
|
goto InvalidUTF8Header;
|
|
|
|
// In the largest buffer case there is one Unicode character per
|
|
// UTF8 character
|
|
if (NULL == (pwszUnicode = (LPWSTR) PkiNonzeroAlloc(
|
|
cbContent * sizeof(WCHAR))))
|
|
goto OutOfMemory;
|
|
|
|
if (0 >= (cchUnicode = UTF8ToWideChar(
|
|
(LPCSTR) pbContent,
|
|
cbContent, // cchUTF8
|
|
pwszUnicode,
|
|
cbContent // cchUnicode
|
|
)))
|
|
goto UTF8ToWideCharError;
|
|
}
|
|
|
|
// Add + sizeof(WCHAR) for added 0 bytes. Want to ensure that the WCHAR
|
|
// string is always null terminated
|
|
lData = cchUnicode * sizeof(WCHAR);
|
|
lAlignExtra = INFO_LEN_ALIGN(lData + sizeof(WCHAR));
|
|
*plRemainExtra -= lAlignExtra;
|
|
if (*plRemainExtra >= 0) {
|
|
*pdwValueType = CERT_RDN_UTF8_STRING;
|
|
pValue->pbData = *ppbExtra;
|
|
pValue->cbData = (DWORD) lData;
|
|
if (lData > 0)
|
|
memcpy(pValue->pbData, pwszUnicode, lData);
|
|
memset(pValue->pbData + lData, 0, sizeof(WCHAR));
|
|
*ppbExtra += lAlignExtra;
|
|
}
|
|
|
|
fResult = TRUE;
|
|
CommonReturn:
|
|
PkiFree(pwszUnicode);
|
|
return fResult;
|
|
|
|
ErrorReturn:
|
|
fResult = FALSE;
|
|
goto CommonReturn;
|
|
SET_ERROR(InvalidUTF8Tag, CRYPT_E_BAD_ENCODE)
|
|
SET_ERROR(InvalidUTF8Header, CRYPT_E_BAD_ENCODE)
|
|
TRACE_ERROR(OutOfMemory)
|
|
TRACE_ERROR(UTF8ToWideCharError)
|
|
}
|
|
|
|
#endif // not defined ASN1_SUPPORTS_UTF8_TAG
|
|
|
|
|
|
//+-------------------------------------------------------------------------
|
|
// Set/Get AnyString
|
|
//--------------------------------------------------------------------------
|
|
void Asn1X509SetAnyString(
|
|
IN DWORD dwValueType,
|
|
IN PCERT_RDN_VALUE_BLOB pValue,
|
|
OUT AnyString *pAsn1
|
|
)
|
|
{
|
|
pAsn1->u.octetString.value = pValue->pbData;
|
|
pAsn1->u.octetString.length = pValue->cbData;
|
|
switch (dwValueType) {
|
|
case CERT_RDN_OCTET_STRING:
|
|
pAsn1->choice = octetString_chosen;
|
|
break;
|
|
case CERT_RDN_NUMERIC_STRING:
|
|
pAsn1->choice = numericString_chosen;
|
|
break;
|
|
case CERT_RDN_PRINTABLE_STRING:
|
|
pAsn1->choice = printableString_chosen;
|
|
break;
|
|
case CERT_RDN_TELETEX_STRING:
|
|
pAsn1->choice = teletexString_chosen;
|
|
break;
|
|
case CERT_RDN_VIDEOTEX_STRING:
|
|
pAsn1->choice = videotexString_chosen;
|
|
break;
|
|
case CERT_RDN_IA5_STRING:
|
|
pAsn1->choice = ia5String_chosen;
|
|
break;
|
|
case CERT_RDN_GRAPHIC_STRING:
|
|
pAsn1->choice = graphicString_chosen;
|
|
break;
|
|
case CERT_RDN_VISIBLE_STRING:
|
|
pAsn1->choice = visibleString_chosen;
|
|
break;
|
|
case CERT_RDN_GENERAL_STRING:
|
|
pAsn1->choice = generalString_chosen;
|
|
break;
|
|
case CERT_RDN_UNIVERSAL_STRING:
|
|
pAsn1->choice = universalString_chosen;
|
|
pAsn1->u.octetString.length = pValue->cbData / 4;
|
|
break;
|
|
case CERT_RDN_BMP_STRING:
|
|
pAsn1->choice = bmpString_chosen;
|
|
pAsn1->u.octetString.length = pValue->cbData / 2;
|
|
break;
|
|
#ifdef ASN1_SUPPORTS_UTF8_TAG
|
|
case CERT_RDN_UTF8_STRING:
|
|
pAsn1->choice = utf8String_chosen;
|
|
pAsn1->u.octetString.length = pValue->cbData / 2;
|
|
break;
|
|
#endif // ASN1_SUPPORTS_UTF8_TAG
|
|
default:
|
|
assert(dwValueType >= CERT_RDN_OCTET_STRING &&
|
|
dwValueType <= CERT_RDN_UTF8_STRING);
|
|
pAsn1->choice = 0;
|
|
}
|
|
}
|
|
|
|
void Asn1X509GetAnyString(
|
|
IN AnyString *pAsn1,
|
|
IN DWORD dwFlags,
|
|
OUT DWORD *pdwValueType,
|
|
OUT PCERT_RDN_VALUE_BLOB pValue,
|
|
IN OUT BYTE **ppbExtra,
|
|
IN OUT LONG *plRemainExtra
|
|
)
|
|
{
|
|
LONG lAlignExtra;
|
|
|
|
DWORD dwValueType;
|
|
BYTE *pbData;
|
|
LONG lData;
|
|
|
|
pbData = pAsn1->u.octetString.value;
|
|
lData = pAsn1->u.octetString.length;
|
|
switch (pAsn1->choice) {
|
|
case octetString_chosen:
|
|
dwValueType = CERT_RDN_OCTET_STRING;
|
|
break;
|
|
case numericString_chosen:
|
|
dwValueType = CERT_RDN_NUMERIC_STRING;
|
|
break;
|
|
case printableString_chosen:
|
|
dwValueType = CERT_RDN_PRINTABLE_STRING;
|
|
break;
|
|
case teletexString_chosen:
|
|
dwValueType = CERT_RDN_TELETEX_STRING;
|
|
break;
|
|
case videotexString_chosen:
|
|
dwValueType = CERT_RDN_VIDEOTEX_STRING;
|
|
break;
|
|
case ia5String_chosen:
|
|
dwValueType = CERT_RDN_IA5_STRING;
|
|
break;
|
|
case graphicString_chosen:
|
|
dwValueType = CERT_RDN_GRAPHIC_STRING;
|
|
break;
|
|
case visibleString_chosen:
|
|
dwValueType = CERT_RDN_VISIBLE_STRING;
|
|
break;
|
|
case generalString_chosen:
|
|
dwValueType = CERT_RDN_GENERAL_STRING;
|
|
break;
|
|
case universalString_chosen:
|
|
dwValueType = CERT_RDN_UNIVERSAL_STRING;
|
|
lData = pAsn1->u.universalString.length * 4;
|
|
break;
|
|
case bmpString_chosen:
|
|
dwValueType = CERT_RDN_BMP_STRING;
|
|
lData = pAsn1->u.bmpString.length * 2;
|
|
break;
|
|
#ifdef ASN1_SUPPORTS_UTF8_TAG
|
|
case utf8String_chosen:
|
|
dwValueType = CERT_RDN_UTF8_STRING;
|
|
lData = pAsn1->u.utf8String.length * 2;
|
|
break;
|
|
#endif // ASN1_SUPPORTS_UTF8_TAG
|
|
default:
|
|
assert(pAsn1->choice >= 1 && pAsn1->choice <= bmpString_chosen);
|
|
dwValueType = 0;
|
|
}
|
|
|
|
// Add + sizeof(WCHAR) for added 0 bytes. Want to ensure that a char
|
|
// or WCHAR string is always null terminated
|
|
lAlignExtra = INFO_LEN_ALIGN(lData + sizeof(WCHAR));
|
|
*plRemainExtra -= lAlignExtra;
|
|
if (*plRemainExtra >= 0) {
|
|
*pdwValueType = dwValueType;
|
|
pValue->pbData = *ppbExtra;
|
|
pValue->cbData = (DWORD) lData;
|
|
if (lData > 0)
|
|
memcpy(pValue->pbData, pbData, lData);
|
|
memset(pValue->pbData + lData, 0, sizeof(WCHAR));
|
|
*ppbExtra += lAlignExtra;
|
|
}
|
|
}
|
|
|
|
|
|
//+-------------------------------------------------------------------------
|
|
// Allocate and Encode AnyString
|
|
//--------------------------------------------------------------------------
|
|
BOOL Asn1X509AllocAndEncodeAnyString(
|
|
IN DWORD dwValueType,
|
|
IN PCERT_RDN_VALUE_BLOB pValue,
|
|
OUT BYTE **ppbEncoded,
|
|
OUT DWORD *pcbEncoded
|
|
)
|
|
{
|
|
BOOL fResult;
|
|
AnyString Asn1String;
|
|
ASN1error_e Asn1Err;
|
|
ASN1encoding_t pEnc = GetEncoder();
|
|
|
|
Asn1X509SetAnyString(dwValueType, pValue, &Asn1String);
|
|
|
|
*ppbEncoded = NULL;
|
|
*pcbEncoded = 0;
|
|
PkiAsn1SetEncodingRule(pEnc, ASN1_BER_RULE_DER);
|
|
if (ASN1_SUCCESS != (Asn1Err = PkiAsn1Encode(
|
|
pEnc,
|
|
&Asn1String,
|
|
AnyString_PDU,
|
|
ppbEncoded,
|
|
pcbEncoded
|
|
)))
|
|
goto Asn1EncodeError;
|
|
|
|
fResult = TRUE;
|
|
|
|
CommonReturn:
|
|
return fResult;
|
|
ErrorReturn:
|
|
fResult = FALSE;
|
|
goto CommonReturn;
|
|
SET_ERROR_VAR(Asn1EncodeError, PkiAsn1ErrToHr(Asn1Err))
|
|
}
|
|
|
|
//+-------------------------------------------------------------------------
|
|
// Set/Free/Get CERT_RDN attribute value
|
|
//--------------------------------------------------------------------------
|
|
BOOL Asn1X509SetRDNAttributeValue(
|
|
IN DWORD dwValueType,
|
|
IN PCERT_RDN_VALUE_BLOB pValue,
|
|
OUT NOCOPYANY *pAsn1
|
|
)
|
|
{
|
|
memset(pAsn1, 0, sizeof(*pAsn1));
|
|
if (dwValueType == CERT_RDN_ANY_TYPE) {
|
|
SetLastError((DWORD) E_INVALIDARG);
|
|
return FALSE;
|
|
}
|
|
|
|
// Determine if value is an encoded representation or is a known string
|
|
// type. Encode accordingly.
|
|
if (dwValueType == CERT_RDN_ENCODED_BLOB) {
|
|
Asn1X509SetAny(pValue, pAsn1);
|
|
#ifndef ASN1_SUPPORTS_UTF8_TAG
|
|
} else if (dwValueType == CERT_RDN_UTF8_STRING) {
|
|
CRYPT_OBJID_BLOB ObjIdBlob;
|
|
|
|
if (!Asn1X509AllocAndEncodeUTF8(
|
|
pValue,
|
|
&ObjIdBlob.pbData,
|
|
&ObjIdBlob.cbData))
|
|
return FALSE;
|
|
Asn1X509SetAny(&ObjIdBlob, pAsn1);
|
|
#endif // not defined ASN1_SUPPORTS_UTF8_TAG
|
|
} else {
|
|
CRYPT_OBJID_BLOB ObjIdBlob;
|
|
|
|
if (!Asn1X509AllocAndEncodeAnyString(
|
|
dwValueType,
|
|
pValue,
|
|
&ObjIdBlob.pbData,
|
|
&ObjIdBlob.cbData))
|
|
return FALSE;
|
|
Asn1X509SetAny(&ObjIdBlob, pAsn1);
|
|
}
|
|
return TRUE;
|
|
}
|
|
|
|
void Asn1X509FreeRDNAttributeValue(
|
|
IN DWORD dwValueType,
|
|
IN OUT NOCOPYANY *pAsn1
|
|
)
|
|
{
|
|
#ifndef ASN1_SUPPORTS_UTF8_TAG
|
|
if (dwValueType == CERT_RDN_UTF8_STRING) {
|
|
Asn1X509FreeEncodedUTF8((BYTE *) pAsn1->encoded);
|
|
pAsn1->encoded = NULL;
|
|
pAsn1->length = 0;
|
|
} else
|
|
#endif // not defined ASN1_SUPPORTS_UTF8_TAG
|
|
if (dwValueType != CERT_RDN_ENCODED_BLOB) {
|
|
if (pAsn1->encoded) {
|
|
DWORD dwErr = GetLastError();
|
|
|
|
// TlsGetValue globbers LastError
|
|
PkiAsn1FreeEncoded(GetEncoder(), pAsn1->encoded);
|
|
pAsn1->encoded = NULL;
|
|
|
|
SetLastError(dwErr);
|
|
}
|
|
pAsn1->length = 0;
|
|
}
|
|
}
|
|
|
|
BOOL Asn1X509GetRDNAttributeValue(
|
|
IN NOCOPYANY *pAsn1,
|
|
IN DWORD dwFlags,
|
|
OUT DWORD *pdwValueType,
|
|
OUT PCERT_RDN_VALUE_BLOB pValue,
|
|
IN OUT BYTE **ppbExtra,
|
|
IN OUT LONG *plRemainExtra
|
|
)
|
|
{
|
|
ASN1decoding_t pDec = GetDecoder();
|
|
AnyString *pAsn1String = NULL;
|
|
|
|
#ifndef ASN1_SUPPORTS_UTF8_TAG
|
|
if (0 < pAsn1->length && UTF8_ASN_TAG == *((BYTE *) pAsn1->encoded))
|
|
return Asn1X509GetUTF8(
|
|
pAsn1,
|
|
dwFlags,
|
|
pdwValueType,
|
|
pValue,
|
|
ppbExtra,
|
|
plRemainExtra
|
|
);
|
|
#endif // not defined ASN1_SUPPORTS_UTF8_TAG
|
|
|
|
|
|
#ifdef OSS_CRYPT_ASN1
|
|
unsigned long ulPrevDecodingFlags;
|
|
|
|
|
|
// Since its acceptable for the following decode to fail, don't output
|
|
// decode errors.
|
|
ulPrevDecodingFlags = ossGetDecodingFlags((POssGlobal) pDec);
|
|
if (ulPrevDecodingFlags & DEBUG_ERRORS)
|
|
ossSetDecodingFlags((POssGlobal) pDec,
|
|
ulPrevDecodingFlags & ~DEBUG_ERRORS);
|
|
ossSetEncodingRules((POssGlobal) pDec, OSS_BER);
|
|
#endif // OSS_CRYPT_ASN1
|
|
|
|
// Check if the value is a string type
|
|
if (ASN1_SUCCESS == PkiAsn1Decode(
|
|
pDec,
|
|
(void **) &pAsn1String,
|
|
AnyString_PDU,
|
|
(BYTE *) pAsn1->encoded,
|
|
pAsn1->length
|
|
)) {
|
|
Asn1X509GetAnyString(pAsn1String, dwFlags, pdwValueType, pValue,
|
|
ppbExtra, plRemainExtra);
|
|
} else {
|
|
// Encoded representation
|
|
if (*plRemainExtra >= 0)
|
|
*pdwValueType = CERT_RDN_ENCODED_BLOB;
|
|
|
|
Asn1X509GetAny(pAsn1, dwFlags, pValue, ppbExtra, plRemainExtra);
|
|
}
|
|
|
|
#ifdef OSS_CRYPT_ASN1
|
|
// Restore previous flags
|
|
if (ulPrevDecodingFlags & DEBUG_ERRORS)
|
|
ossSetDecodingFlags((POssGlobal) pDec, ulPrevDecodingFlags);
|
|
#endif // OSS_CRYPT_ASN1
|
|
|
|
PkiAsn1FreeDecoded(
|
|
pDec,
|
|
pAsn1String,
|
|
AnyString_PDU
|
|
);
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
//+-------------------------------------------------------------------------
|
|
// Set/Free/Get CERT_RDN attribute
|
|
//--------------------------------------------------------------------------
|
|
BOOL Asn1X509SetRDNAttribute(
|
|
IN PCERT_RDN_ATTR pInfo,
|
|
OUT AttributeTypeValue *pAsn1
|
|
)
|
|
{
|
|
memset(pAsn1, 0, sizeof(*pAsn1));
|
|
if (pInfo->pszObjId) {
|
|
if (!Asn1X509SetEncodedObjId(pInfo->pszObjId, &pAsn1->type))
|
|
return FALSE;
|
|
}
|
|
|
|
return Asn1X509SetRDNAttributeValue(
|
|
pInfo->dwValueType,
|
|
&pInfo->Value,
|
|
&pAsn1->value
|
|
);
|
|
}
|
|
|
|
void Asn1X509FreeRDNAttribute(
|
|
IN PCERT_RDN_ATTR pInfo,
|
|
IN OUT AttributeTypeValue *pAsn1
|
|
)
|
|
{
|
|
Asn1X509FreeRDNAttributeValue(
|
|
pInfo->dwValueType,
|
|
&pAsn1->value
|
|
);
|
|
}
|
|
|
|
BOOL Asn1X509GetRDNAttribute(
|
|
IN AttributeTypeValue *pAsn1,
|
|
IN DWORD dwFlags,
|
|
OUT PCERT_RDN_ATTR pInfo,
|
|
IN OUT BYTE **ppbExtra,
|
|
IN OUT LONG *plRemainExtra
|
|
)
|
|
{
|
|
// Get ObjectIdentifier
|
|
Asn1X509GetEncodedObjId(&pAsn1->type, dwFlags, &pInfo->pszObjId,
|
|
ppbExtra, plRemainExtra);
|
|
|
|
// Get value
|
|
return Asn1X509GetRDNAttributeValue(&pAsn1->value, dwFlags,
|
|
&pInfo->dwValueType, &pInfo->Value, ppbExtra, plRemainExtra);
|
|
}
|
|
|
|
//+-------------------------------------------------------------------------
|
|
// Set/Free/Get SeqOfAny
|
|
//--------------------------------------------------------------------------
|
|
BOOL WINAPI Asn1X509SetSeqOfAny(
|
|
IN DWORD cValue,
|
|
IN PCRYPT_DER_BLOB pValue,
|
|
#ifdef OSS_CRYPT_ASN1
|
|
OUT unsigned int *pAsn1Count,
|
|
#else
|
|
OUT ASN1uint32_t *pAsn1Count,
|
|
#endif // OSS_CRYPT_ASN1
|
|
OUT NOCOPYANY **ppAsn1Value
|
|
)
|
|
{
|
|
|
|
*pAsn1Count = 0;
|
|
*ppAsn1Value = NULL;
|
|
if (cValue > 0) {
|
|
NOCOPYANY *pAsn1Value;
|
|
|
|
pAsn1Value = (NOCOPYANY *) PkiZeroAlloc(cValue * sizeof(NOCOPYANY));
|
|
if (pAsn1Value == NULL)
|
|
return FALSE;
|
|
*pAsn1Count = cValue;
|
|
*ppAsn1Value = pAsn1Value;
|
|
for ( ; cValue > 0; cValue--, pValue++, pAsn1Value++)
|
|
Asn1X509SetAny(pValue, pAsn1Value);
|
|
}
|
|
return TRUE;
|
|
}
|
|
|
|
void Asn1X509FreeSeqOfAny(
|
|
IN NOCOPYANY *pAsn1Value
|
|
)
|
|
{
|
|
if (pAsn1Value)
|
|
PkiFree(pAsn1Value);
|
|
}
|
|
|
|
void Asn1X509GetSeqOfAny(
|
|
IN unsigned int Asn1Count,
|
|
IN NOCOPYANY *pAsn1Value,
|
|
IN DWORD dwFlags,
|
|
OUT DWORD *pcValue,
|
|
OUT PCRYPT_DER_BLOB *ppValue,
|
|
IN OUT BYTE **ppbExtra,
|
|
IN OUT LONG *plRemainExtra
|
|
)
|
|
{
|
|
LONG lAlignExtra;
|
|
PCRYPT_ATTR_BLOB pValue;
|
|
|
|
lAlignExtra = INFO_LEN_ALIGN(Asn1Count * sizeof(CRYPT_DER_BLOB));
|
|
*plRemainExtra -= lAlignExtra;
|
|
if (*plRemainExtra >= 0) {
|
|
*pcValue = Asn1Count;
|
|
pValue = (PCRYPT_DER_BLOB) *ppbExtra;
|
|
*ppValue = pValue;
|
|
*ppbExtra += lAlignExtra;
|
|
} else
|
|
pValue = NULL;
|
|
|
|
for (; Asn1Count > 0; Asn1Count--, pAsn1Value++, pValue++)
|
|
Asn1X509GetAny(pAsn1Value, dwFlags, pValue, ppbExtra, plRemainExtra);
|
|
}
|
|
|
|
|
|
//+-------------------------------------------------------------------------
|
|
// Set/Free/Get CRYPT_ATTRIBUTE
|
|
//--------------------------------------------------------------------------
|
|
BOOL WINAPI Asn1X509SetAttribute(
|
|
IN PCRYPT_ATTRIBUTE pInfo,
|
|
OUT Attribute *pAsn1
|
|
)
|
|
{
|
|
memset(pAsn1, 0, sizeof(*pAsn1));
|
|
if (!Asn1X509SetEncodedObjId(pInfo->pszObjId, &pAsn1->type))
|
|
return FALSE;
|
|
|
|
return Asn1X509SetSeqOfAny(
|
|
pInfo->cValue,
|
|
pInfo->rgValue,
|
|
&pAsn1->values.count,
|
|
&pAsn1->values.value);
|
|
}
|
|
|
|
void Asn1X509FreeAttribute(
|
|
IN OUT Attribute *pAsn1
|
|
)
|
|
{
|
|
Asn1X509FreeSeqOfAny(pAsn1->values.value);
|
|
}
|
|
|
|
void Asn1X509GetAttribute(
|
|
IN Attribute *pAsn1,
|
|
IN DWORD dwFlags,
|
|
OUT PCRYPT_ATTRIBUTE pInfo,
|
|
IN OUT BYTE **ppbExtra,
|
|
IN OUT LONG *plRemainExtra
|
|
)
|
|
{
|
|
Asn1X509GetEncodedObjId(&pAsn1->type, dwFlags,
|
|
&pInfo->pszObjId, ppbExtra, plRemainExtra);
|
|
Asn1X509GetSeqOfAny(pAsn1->values.count, pAsn1->values.value, dwFlags,
|
|
&pInfo->cValue, &pInfo->rgValue, ppbExtra, plRemainExtra);
|
|
}
|
|
|
|
//+-------------------------------------------------------------------------
|
|
// Set/Free/Get Attributes
|
|
//--------------------------------------------------------------------------
|
|
BOOL Asn1X509SetAttributes(
|
|
IN DWORD cAttribute,
|
|
IN PCRYPT_ATTRIBUTE pAttribute,
|
|
OUT Attributes *pAsn1
|
|
)
|
|
{
|
|
Attribute *pAsn1Attr;
|
|
|
|
pAsn1->value = NULL;
|
|
pAsn1->count = 0;
|
|
if (cAttribute == 0)
|
|
return TRUE;
|
|
|
|
pAsn1Attr = (Attribute *) PkiZeroAlloc(cAttribute * sizeof(Attribute));
|
|
if (pAsn1Attr == NULL)
|
|
return FALSE;
|
|
pAsn1->value = pAsn1Attr;
|
|
pAsn1->count = cAttribute;
|
|
|
|
for ( ; cAttribute > 0; cAttribute--, pAttribute++, pAsn1Attr++) {
|
|
if (!Asn1X509SetAttribute(pAttribute, pAsn1Attr))
|
|
return FALSE;
|
|
}
|
|
return TRUE;
|
|
}
|
|
|
|
void Asn1X509FreeAttributes(
|
|
IN Attributes *pAsn1
|
|
)
|
|
{
|
|
if (pAsn1->value) {
|
|
DWORD cAttr = pAsn1->count;
|
|
Attribute *pAsn1Attr = pAsn1->value;
|
|
|
|
for ( ; cAttr > 0; cAttr--, pAsn1Attr++)
|
|
Asn1X509FreeAttribute(pAsn1Attr);
|
|
|
|
PkiFree(pAsn1->value);
|
|
pAsn1->value = NULL;
|
|
}
|
|
pAsn1->count = 0;
|
|
}
|
|
|
|
void Asn1X509GetAttributes(
|
|
IN Attributes *pAsn1,
|
|
IN DWORD dwFlags,
|
|
OUT DWORD *pcAttribute,
|
|
OUT PCRYPT_ATTRIBUTE *ppAttribute,
|
|
IN OUT BYTE **ppbExtra,
|
|
IN OUT LONG *plRemainExtra
|
|
)
|
|
{
|
|
LONG lRemainExtra = *plRemainExtra;
|
|
BYTE *pbExtra = *ppbExtra;
|
|
LONG lAlignExtra;
|
|
|
|
DWORD cAttr;
|
|
Attribute *pAsn1Attr;
|
|
PCRYPT_ATTRIBUTE pGetAttr;
|
|
|
|
cAttr = pAsn1->count;
|
|
lAlignExtra = INFO_LEN_ALIGN(cAttr * sizeof(CRYPT_ATTRIBUTE));
|
|
lRemainExtra -= lAlignExtra;
|
|
if (lRemainExtra >= 0) {
|
|
*pcAttribute = cAttr;
|
|
pGetAttr = (PCRYPT_ATTRIBUTE) pbExtra;
|
|
*ppAttribute = pGetAttr;
|
|
pbExtra += lAlignExtra;
|
|
} else
|
|
pGetAttr = NULL;
|
|
|
|
pAsn1Attr = pAsn1->value;
|
|
for ( ; cAttr > 0; cAttr--, pAsn1Attr++, pGetAttr++) {
|
|
Asn1X509GetAttribute(pAsn1Attr, dwFlags, pGetAttr,
|
|
&pbExtra, &lRemainExtra);
|
|
}
|
|
|
|
*plRemainExtra = lRemainExtra;
|
|
*ppbExtra = pbExtra;
|
|
}
|
|
|
|
//+-------------------------------------------------------------------------
|
|
// Set/Free/Get CERT_ALT_NAME_ENTRY
|
|
//--------------------------------------------------------------------------
|
|
BOOL Asn1X509SetAltNameEntry(
|
|
IN PCERT_ALT_NAME_ENTRY pInfo,
|
|
OUT GeneralName *pAsn1,
|
|
IN DWORD dwEntryIndex,
|
|
OUT DWORD *pdwErrLocation
|
|
)
|
|
{
|
|
BOOL fResult;
|
|
|
|
// Assumption: ASN1 choice == dwAltNameChoice
|
|
// Asn1X509GetAltNameEntry has asserts to verify
|
|
pAsn1->choice = (unsigned short) pInfo->dwAltNameChoice;
|
|
|
|
*pdwErrLocation = 0;
|
|
|
|
switch (pInfo->dwAltNameChoice) {
|
|
case CERT_ALT_NAME_OTHER_NAME:
|
|
if (!Asn1X509SetEncodedObjId(pInfo->pOtherName->pszObjId,
|
|
&pAsn1->u.otherName.type))
|
|
goto ErrorReturn;
|
|
Asn1X509SetAny(&pInfo->pOtherName->Value, &pAsn1->u.otherName.value);
|
|
break;
|
|
case CERT_ALT_NAME_DIRECTORY_NAME:
|
|
Asn1X509SetAny(&pInfo->DirectoryName, &pAsn1->u.directoryName);
|
|
break;
|
|
case CERT_ALT_NAME_RFC822_NAME:
|
|
case CERT_ALT_NAME_DNS_NAME:
|
|
case CERT_ALT_NAME_URL:
|
|
if (!Asn1X509SetUnicodeConvertedToIA5(pInfo->pwszRfc822Name,
|
|
&pAsn1->u.rfc822Name, dwEntryIndex, pdwErrLocation))
|
|
goto ErrorReturn;
|
|
break;
|
|
case CERT_ALT_NAME_IP_ADDRESS:
|
|
Asn1X509SetOctetString(&pInfo->IPAddress, &pAsn1->u.iPAddress);
|
|
break;
|
|
case CERT_ALT_NAME_REGISTERED_ID:
|
|
if (!Asn1X509SetEncodedObjId(pInfo->pszRegisteredID, &pAsn1->u.registeredID))
|
|
goto ErrorReturn;
|
|
break;
|
|
case CERT_ALT_NAME_X400_ADDRESS:
|
|
case CERT_ALT_NAME_EDI_PARTY_NAME:
|
|
default:
|
|
SetLastError((DWORD) E_INVALIDARG);
|
|
goto ErrorReturn;
|
|
}
|
|
|
|
fResult = TRUE;
|
|
CommonReturn:
|
|
return fResult;
|
|
|
|
ErrorReturn:
|
|
fResult = FALSE;
|
|
goto CommonReturn;
|
|
}
|
|
|
|
void Asn1X509FreeAltNameEntry(
|
|
IN GeneralName *pAsn1
|
|
)
|
|
{
|
|
switch (pAsn1->choice) {
|
|
case CERT_ALT_NAME_RFC822_NAME:
|
|
case CERT_ALT_NAME_DNS_NAME:
|
|
case CERT_ALT_NAME_URL:
|
|
Asn1X509FreeUnicodeConvertedToIA5(&pAsn1->u.rfc822Name);
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
}
|
|
|
|
BOOL Asn1X509GetAltNameEntry(
|
|
IN GeneralName *pAsn1,
|
|
IN DWORD dwFlags,
|
|
OUT PCERT_ALT_NAME_ENTRY pInfo,
|
|
IN OUT BYTE **ppbExtra,
|
|
IN OUT LONG *plRemainExtra
|
|
)
|
|
{
|
|
DWORD dwAltNameChoice;
|
|
|
|
assert(otherName_chosen == CERT_ALT_NAME_OTHER_NAME);
|
|
assert(rfc822Name_chosen == CERT_ALT_NAME_RFC822_NAME);
|
|
assert(dNSName_chosen == CERT_ALT_NAME_DNS_NAME);
|
|
assert(x400Address_chosen == CERT_ALT_NAME_X400_ADDRESS);
|
|
assert(directoryName_chosen == CERT_ALT_NAME_DIRECTORY_NAME);
|
|
assert(ediPartyName_chosen == CERT_ALT_NAME_EDI_PARTY_NAME);
|
|
assert(uniformResourceLocator_chosen == CERT_ALT_NAME_URL);
|
|
assert(iPAddress_chosen == CERT_ALT_NAME_IP_ADDRESS);
|
|
assert(registeredID_chosen == CERT_ALT_NAME_REGISTERED_ID);
|
|
|
|
|
|
dwAltNameChoice = pAsn1->choice;
|
|
if (*plRemainExtra >= 0)
|
|
pInfo->dwAltNameChoice = dwAltNameChoice;
|
|
switch (dwAltNameChoice) {
|
|
case CERT_ALT_NAME_OTHER_NAME:
|
|
{
|
|
LONG lAlignExtra;
|
|
PCERT_OTHER_NAME pOtherName;
|
|
|
|
lAlignExtra = INFO_LEN_ALIGN(sizeof(CERT_OTHER_NAME));
|
|
*plRemainExtra -= lAlignExtra;
|
|
if (*plRemainExtra >= 0) {
|
|
pOtherName = (PCERT_OTHER_NAME) *ppbExtra;
|
|
pInfo->pOtherName = pOtherName;
|
|
*ppbExtra += lAlignExtra;
|
|
} else
|
|
pOtherName = NULL;
|
|
|
|
Asn1X509GetEncodedObjId(&pAsn1->u.otherName.type, dwFlags,
|
|
&pOtherName->pszObjId, ppbExtra, plRemainExtra);
|
|
Asn1X509GetAny(&pAsn1->u.otherName.value, dwFlags,
|
|
&pOtherName->Value, ppbExtra, plRemainExtra);
|
|
}
|
|
break;
|
|
case CERT_ALT_NAME_DIRECTORY_NAME:
|
|
Asn1X509GetAny(&pAsn1->u.directoryName, dwFlags,
|
|
&pInfo->DirectoryName, ppbExtra, plRemainExtra);
|
|
break;
|
|
case CERT_ALT_NAME_RFC822_NAME:
|
|
case CERT_ALT_NAME_DNS_NAME:
|
|
case CERT_ALT_NAME_URL:
|
|
Asn1X509GetIA5ConvertedToUnicode(&pAsn1->u.rfc822Name, dwFlags,
|
|
&pInfo->pwszRfc822Name, ppbExtra, plRemainExtra);
|
|
break;
|
|
case CERT_ALT_NAME_IP_ADDRESS:
|
|
Asn1X509GetOctetString(&pAsn1->u.iPAddress, dwFlags,
|
|
&pInfo->IPAddress, ppbExtra, plRemainExtra);
|
|
break;
|
|
case CERT_ALT_NAME_REGISTERED_ID:
|
|
Asn1X509GetEncodedObjId(&pAsn1->u.registeredID, dwFlags,
|
|
&pInfo->pszRegisteredID, ppbExtra, plRemainExtra);
|
|
break;
|
|
case CERT_ALT_NAME_X400_ADDRESS:
|
|
case CERT_ALT_NAME_EDI_PARTY_NAME:
|
|
break;
|
|
default:
|
|
SetLastError((DWORD) CRYPT_E_BAD_ENCODE);
|
|
return FALSE;
|
|
}
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
|
|
//+-------------------------------------------------------------------------
|
|
// Set/Free/Get CERT_ALT_NAME_INFO
|
|
//--------------------------------------------------------------------------
|
|
BOOL Asn1X509SetAltNames(
|
|
IN PCERT_ALT_NAME_INFO pInfo,
|
|
OUT AltNames *pAsn1,
|
|
IN DWORD dwIndex,
|
|
OUT DWORD *pdwErrLocation
|
|
)
|
|
{
|
|
BOOL fResult;
|
|
DWORD i;
|
|
DWORD cEntry;
|
|
PCERT_ALT_NAME_ENTRY pEntry;
|
|
GeneralName *pAsn1Entry = NULL;
|
|
|
|
*pdwErrLocation = 0;
|
|
|
|
cEntry = pInfo->cAltEntry;
|
|
pEntry = pInfo->rgAltEntry;
|
|
pAsn1->count = cEntry;
|
|
pAsn1->value = NULL;
|
|
if (cEntry > 0) {
|
|
pAsn1Entry =
|
|
(GeneralName *) PkiZeroAlloc(cEntry * sizeof(GeneralName));
|
|
if (pAsn1Entry == NULL)
|
|
goto ErrorReturn;
|
|
pAsn1->value = pAsn1Entry;
|
|
}
|
|
|
|
// Array of AltName entries
|
|
for (i = 0; i < cEntry; i++, pEntry++, pAsn1Entry++) {
|
|
if (!Asn1X509SetAltNameEntry(pEntry, pAsn1Entry,
|
|
(dwIndex << 8) | i, pdwErrLocation))
|
|
goto ErrorReturn;
|
|
}
|
|
|
|
fResult = TRUE;
|
|
CommonReturn:
|
|
return fResult;
|
|
|
|
ErrorReturn:
|
|
fResult = FALSE;
|
|
goto CommonReturn;
|
|
}
|
|
|
|
void Asn1X509FreeAltNames(
|
|
OUT AltNames *pAsn1
|
|
)
|
|
{
|
|
if (pAsn1->value) {
|
|
DWORD cEntry = pAsn1->count;
|
|
GeneralName *pAsn1Entry = pAsn1->value;
|
|
for ( ; cEntry > 0; cEntry--, pAsn1Entry++)
|
|
Asn1X509FreeAltNameEntry(pAsn1Entry);
|
|
PkiFree(pAsn1->value);
|
|
}
|
|
}
|
|
|
|
BOOL Asn1X509GetAltNames(
|
|
IN AltNames *pAsn1,
|
|
IN DWORD dwFlags,
|
|
OUT PCERT_ALT_NAME_INFO pInfo,
|
|
IN OUT BYTE **ppbExtra,
|
|
IN OUT LONG *plRemainExtra
|
|
)
|
|
{
|
|
LONG lAlignExtra;
|
|
DWORD cEntry;
|
|
PCERT_ALT_NAME_ENTRY pEntry;
|
|
GeneralName *pAsn1Entry;
|
|
|
|
cEntry = pAsn1->count;
|
|
lAlignExtra = INFO_LEN_ALIGN(cEntry * sizeof(CERT_ALT_NAME_ENTRY));
|
|
*plRemainExtra -= lAlignExtra;
|
|
if (*plRemainExtra >= 0) {
|
|
pInfo->cAltEntry = cEntry;
|
|
pEntry = (PCERT_ALT_NAME_ENTRY) *ppbExtra;
|
|
pInfo->rgAltEntry = pEntry;
|
|
*ppbExtra += lAlignExtra;
|
|
} else
|
|
pEntry = NULL;
|
|
|
|
// Array of AltName entries
|
|
pAsn1Entry = pAsn1->value;
|
|
for (; cEntry > 0; cEntry--, pEntry++, pAsn1Entry++) {
|
|
if (!Asn1X509GetAltNameEntry(pAsn1Entry, dwFlags,
|
|
pEntry, ppbExtra, plRemainExtra))
|
|
return FALSE;
|
|
}
|
|
return TRUE;
|
|
}
|
|
|
|
//+-------------------------------------------------------------------------
|
|
// Set/Free/Get CERT_ACCESS_DESCRIPTION
|
|
//--------------------------------------------------------------------------
|
|
BOOL Asn1X509SetAccessDescriptions(
|
|
IN DWORD cAccDescr,
|
|
IN PCERT_ACCESS_DESCRIPTION pAccDescr,
|
|
OUT AccessDescription *pAsn1,
|
|
OUT DWORD *pdwErrLocation
|
|
)
|
|
{
|
|
BOOL fResult;
|
|
DWORD i;
|
|
|
|
*pdwErrLocation = 0;
|
|
for (i = 0; i < cAccDescr; i++, pAccDescr++, pAsn1++) {
|
|
if (!Asn1X509SetEncodedObjId(pAccDescr->pszAccessMethod, &pAsn1->accessMethod))
|
|
goto ErrorReturn;
|
|
if (!Asn1X509SetAltNameEntry(&pAccDescr->AccessLocation,
|
|
&pAsn1->accessLocation,
|
|
i,
|
|
pdwErrLocation))
|
|
goto ErrorReturn;
|
|
}
|
|
|
|
fResult = TRUE;
|
|
CommonReturn:
|
|
return fResult;
|
|
|
|
ErrorReturn:
|
|
fResult = FALSE;
|
|
goto CommonReturn;
|
|
}
|
|
|
|
void Asn1X509FreeAccessDescriptions(
|
|
IN DWORD cAccDescr,
|
|
IN OUT AccessDescription *pAsn1
|
|
)
|
|
{
|
|
for ( ; cAccDescr > 0; cAccDescr--, pAsn1++)
|
|
Asn1X509FreeAltNameEntry(&pAsn1->accessLocation);
|
|
}
|
|
|
|
BOOL Asn1X509GetAccessDescriptions(
|
|
IN DWORD cAccDescr,
|
|
IN AccessDescription *pAsn1,
|
|
IN DWORD dwFlags,
|
|
IN PCERT_ACCESS_DESCRIPTION pAccDescr,
|
|
IN OUT BYTE **ppbExtra,
|
|
IN OUT LONG *plRemainExtra
|
|
)
|
|
{
|
|
// Array of AccessDescription entries
|
|
for (; cAccDescr > 0; cAccDescr--, pAccDescr++, pAsn1++) {
|
|
Asn1X509GetEncodedObjId(&pAsn1->accessMethod, dwFlags,
|
|
&pAccDescr->pszAccessMethod, ppbExtra, plRemainExtra);
|
|
if (!Asn1X509GetAltNameEntry(&pAsn1->accessLocation, dwFlags,
|
|
&pAccDescr->AccessLocation, ppbExtra, plRemainExtra))
|
|
return FALSE;
|
|
}
|
|
return TRUE;
|
|
}
|
|
|
|
//+-------------------------------------------------------------------------
|
|
// Encode the Cert Info (ASN1 X509 v3 ASN.1)
|
|
//--------------------------------------------------------------------------
|
|
BOOL WINAPI Asn1X509CertInfoEncodeEx(
|
|
IN DWORD dwCertEncodingType,
|
|
IN LPCSTR lpszStructType,
|
|
IN PCERT_INFO pInfo,
|
|
IN DWORD dwFlags,
|
|
IN OPTIONAL PCRYPT_ENCODE_PARA pEncodePara,
|
|
OUT OPTIONAL void *pvEncoded,
|
|
IN OUT DWORD *pcbEncoded
|
|
)
|
|
{
|
|
BOOL fResult;
|
|
CertificateToBeSigned Cert;
|
|
|
|
memset(&Cert, 0, sizeof(Cert));
|
|
if (pInfo->dwVersion != 0) {
|
|
#ifdef OSS_CRYPT_ASN1
|
|
Cert.CertificateToBeSigned_version = pInfo->dwVersion;
|
|
#else
|
|
Cert.version = pInfo->dwVersion;
|
|
#endif // OSS_CRYPT_ASN1
|
|
Cert.bit_mask |= CertificateToBeSigned_version_present;
|
|
}
|
|
|
|
if (!Asn1X509SetHugeInteger(&pInfo->SerialNumber, &Cert.serialNumber))
|
|
goto ErrorReturn;
|
|
if (!Asn1X509SetAlgorithm(&pInfo->SignatureAlgorithm, &Cert.signature,
|
|
CRYPT_SIGN_ALG_OID_GROUP_ID))
|
|
goto ErrorReturn;
|
|
Asn1X509SetAny(&pInfo->Issuer, &Cert.issuer);
|
|
if (!PkiAsn1ToChoiceOfTime(&pInfo->NotBefore,
|
|
&Cert.validity.notBefore.choice,
|
|
&Cert.validity.notBefore.u.generalTime,
|
|
&Cert.validity.notBefore.u.utcTime
|
|
))
|
|
goto EncodeError;
|
|
if (!PkiAsn1ToChoiceOfTime(&pInfo->NotAfter,
|
|
&Cert.validity.notAfter.choice,
|
|
&Cert.validity.notAfter.u.generalTime,
|
|
&Cert.validity.notAfter.u.utcTime
|
|
))
|
|
goto EncodeError;
|
|
Asn1X509SetAny(&pInfo->Subject, &Cert.subject);
|
|
if (!Asn1X509SetPublicKeyInfo(&pInfo->SubjectPublicKeyInfo,
|
|
&Cert.subjectPublicKeyInfo))
|
|
goto ErrorReturn;
|
|
|
|
if (pInfo->IssuerUniqueId.cbData) {
|
|
Asn1X509SetBit(&pInfo->IssuerUniqueId, &Cert.issuerUniqueIdentifier);
|
|
Cert.bit_mask |= issuerUniqueIdentifier_present;
|
|
}
|
|
if (pInfo->SubjectUniqueId.cbData) {
|
|
Asn1X509SetBit(&pInfo->SubjectUniqueId, &Cert.subjectUniqueIdentifier);
|
|
Cert.bit_mask |= subjectUniqueIdentifier_present;
|
|
}
|
|
if (pInfo->cExtension) {
|
|
if (!Asn1X509SetExtensions(pInfo->cExtension, pInfo->rgExtension,
|
|
&Cert.extensions))
|
|
goto ErrorReturn;
|
|
Cert.bit_mask |= extensions_present;
|
|
}
|
|
|
|
fResult = Asn1InfoEncodeEx(
|
|
CertificateToBeSigned_PDU,
|
|
&Cert,
|
|
dwFlags,
|
|
pEncodePara,
|
|
pvEncoded,
|
|
pcbEncoded
|
|
);
|
|
goto CommonReturn;
|
|
|
|
EncodeError:
|
|
SetLastError((DWORD) CRYPT_E_BAD_ENCODE);
|
|
ErrorReturn:
|
|
if (dwFlags & CRYPT_ENCODE_ALLOC_FLAG)
|
|
*((void **) pvEncoded) = NULL;
|
|
*pcbEncoded = 0;
|
|
fResult = FALSE;
|
|
CommonReturn:
|
|
Asn1X509FreeHugeInteger(&Cert.serialNumber);
|
|
Asn1X509FreeExtensions(&Cert.extensions);
|
|
return fResult;
|
|
}
|
|
|
|
//+-------------------------------------------------------------------------
|
|
// Decode the Cert Info (ASN1 X509 v3 ASN.1)
|
|
//--------------------------------------------------------------------------
|
|
BOOL WINAPI Asn1X509CertInfoDecodeExCallback(
|
|
IN void *pvAsn1Info,
|
|
IN DWORD dwFlags,
|
|
IN OPTIONAL PCRYPT_DECODE_PARA pDecodePara,
|
|
OUT OPTIONAL void *pvStructInfo,
|
|
IN OUT LONG *plRemainExtra
|
|
)
|
|
{
|
|
BOOL fResult;
|
|
CertificateToBeSigned *pCert = (CertificateToBeSigned *) pvAsn1Info;
|
|
PCERT_INFO pInfo = (PCERT_INFO) pvStructInfo;
|
|
LONG lRemainExtra = *plRemainExtra;
|
|
BYTE *pbExtra;
|
|
|
|
lRemainExtra -= sizeof(CERT_INFO);
|
|
if (lRemainExtra < 0) {
|
|
pbExtra = NULL;
|
|
} else {
|
|
// Default all optional fields to zero
|
|
memset(pInfo, 0, sizeof(CERT_INFO));
|
|
|
|
// Update fields not needing extra memory after the CERT_INFO
|
|
if (pCert->bit_mask & CertificateToBeSigned_version_present)
|
|
#ifdef OSS_CRYPT_ASN1
|
|
pInfo->dwVersion = pCert->CertificateToBeSigned_version;
|
|
#else
|
|
pInfo->dwVersion = pCert->version;
|
|
#endif // OSS_CRYPT_ASN1
|
|
if (!PkiAsn1FromChoiceOfTime(pCert->validity.notBefore.choice,
|
|
&pCert->validity.notBefore.u.generalTime,
|
|
&pCert->validity.notBefore.u.utcTime,
|
|
&pInfo->NotBefore))
|
|
goto DecodeError;
|
|
if (!PkiAsn1FromChoiceOfTime(pCert->validity.notAfter.choice,
|
|
&pCert->validity.notAfter.u.generalTime,
|
|
&pCert->validity.notAfter.u.utcTime,
|
|
&pInfo->NotAfter))
|
|
goto DecodeError;
|
|
pbExtra = (BYTE *) pInfo + sizeof(CERT_INFO);
|
|
}
|
|
|
|
Asn1X509GetHugeInteger(&pCert->serialNumber, dwFlags,
|
|
&pInfo->SerialNumber, &pbExtra, &lRemainExtra);
|
|
Asn1X509GetAlgorithm(&pCert->signature, dwFlags,
|
|
&pInfo->SignatureAlgorithm, &pbExtra, &lRemainExtra);
|
|
Asn1X509GetAny(&pCert->issuer, dwFlags,
|
|
&pInfo->Issuer, &pbExtra, &lRemainExtra);
|
|
Asn1X509GetAny(&pCert->subject, dwFlags,
|
|
&pInfo->Subject, &pbExtra, &lRemainExtra);
|
|
Asn1X509GetPublicKeyInfo(&pCert->subjectPublicKeyInfo, dwFlags,
|
|
&pInfo->SubjectPublicKeyInfo, &pbExtra, &lRemainExtra);
|
|
|
|
if (pCert->bit_mask & issuerUniqueIdentifier_present)
|
|
Asn1X509GetBit(&pCert->issuerUniqueIdentifier, dwFlags,
|
|
&pInfo->IssuerUniqueId, &pbExtra, &lRemainExtra);
|
|
if (pCert->bit_mask & subjectUniqueIdentifier_present)
|
|
Asn1X509GetBit(&pCert->subjectUniqueIdentifier, dwFlags,
|
|
&pInfo->SubjectUniqueId, &pbExtra, &lRemainExtra);
|
|
if (pCert->bit_mask & extensions_present)
|
|
Asn1X509GetExtensions(&pCert->extensions, dwFlags,
|
|
&pInfo->cExtension, &pInfo->rgExtension, &pbExtra, &lRemainExtra);
|
|
|
|
fResult = TRUE;
|
|
CommonReturn:
|
|
*plRemainExtra = lRemainExtra;
|
|
return fResult;
|
|
|
|
ErrorReturn:
|
|
fResult = FALSE;
|
|
goto CommonReturn;
|
|
|
|
SET_ERROR(DecodeError, CRYPT_E_BAD_ENCODE)
|
|
}
|
|
|
|
BOOL WINAPI Asn1X509CertInfoDecodeEx(
|
|
IN DWORD dwCertEncodingType,
|
|
IN LPCSTR lpszStructType,
|
|
IN const BYTE *pbEncoded,
|
|
IN DWORD cbEncoded,
|
|
IN DWORD dwFlags,
|
|
IN OPTIONAL PCRYPT_DECODE_PARA pDecodePara,
|
|
OUT OPTIONAL void *pvStructInfo,
|
|
IN OUT DWORD *pcbStructInfo
|
|
)
|
|
{
|
|
const BYTE *pbToBeSigned;
|
|
DWORD cbToBeSigned;
|
|
|
|
if ((dwFlags & CRYPT_DECODE_TO_BE_SIGNED_FLAG) ||
|
|
!Asn1UtilExtractCertificateToBeSignedContent(
|
|
pbEncoded,
|
|
cbEncoded,
|
|
&cbToBeSigned,
|
|
&pbToBeSigned
|
|
)) {
|
|
pbToBeSigned = pbEncoded;
|
|
cbToBeSigned = cbEncoded;
|
|
}
|
|
|
|
return Asn1InfoDecodeAndAllocEx(
|
|
CertificateToBeSigned_PDU,
|
|
pbToBeSigned,
|
|
cbToBeSigned,
|
|
dwFlags,
|
|
pDecodePara,
|
|
Asn1X509CertInfoDecodeExCallback,
|
|
pvStructInfo,
|
|
pcbStructInfo
|
|
);
|
|
}
|
|
|
|
//+-------------------------------------------------------------------------
|
|
// Encode the CRL Info (ASN1 X509 ASN.1)
|
|
//--------------------------------------------------------------------------
|
|
BOOL WINAPI Asn1X509CrlInfoEncodeEx(
|
|
IN DWORD dwCertEncodingType,
|
|
IN LPCSTR lpszStructType,
|
|
IN PCRL_INFO pInfo,
|
|
IN DWORD dwFlags,
|
|
IN OPTIONAL PCRYPT_ENCODE_PARA pEncodePara,
|
|
OUT OPTIONAL void *pvEncoded,
|
|
IN OUT DWORD *pcbEncoded
|
|
)
|
|
{
|
|
BOOL fResult;
|
|
CertificateRevocationListToBeSigned Crl;
|
|
|
|
memset(&Crl, 0, sizeof(Crl));
|
|
|
|
if (pInfo->dwVersion != 0) {
|
|
#ifdef OSS_CRYPT_ASN1
|
|
Crl.CertificateRevocationListToBeSigned_version = pInfo->dwVersion;
|
|
#else
|
|
Crl.version = pInfo->dwVersion;
|
|
#endif // OSS_CRYPT_ASN1
|
|
Crl.bit_mask |= CertificateRevocationListToBeSigned_version_present;
|
|
}
|
|
if (!Asn1X509SetAlgorithm(&pInfo->SignatureAlgorithm, &Crl.signature,
|
|
CRYPT_SIGN_ALG_OID_GROUP_ID))
|
|
goto ErrorReturn;
|
|
Asn1X509SetAny(&pInfo->Issuer, &Crl.issuer);
|
|
if (!PkiAsn1ToChoiceOfTime(&pInfo->ThisUpdate,
|
|
&Crl.thisUpdate.choice,
|
|
&Crl.thisUpdate.u.generalTime,
|
|
&Crl.thisUpdate.u.utcTime
|
|
))
|
|
goto EncodeError;
|
|
if (pInfo->NextUpdate.dwLowDateTime || pInfo->NextUpdate.dwHighDateTime) {
|
|
Crl.bit_mask |= nextUpdate_present;
|
|
if (!PkiAsn1ToChoiceOfTime(&pInfo->NextUpdate,
|
|
&Crl.nextUpdate.choice,
|
|
&Crl.nextUpdate.u.generalTime,
|
|
&Crl.nextUpdate.u.utcTime
|
|
))
|
|
goto EncodeError;
|
|
}
|
|
if (pInfo->cCRLEntry) {
|
|
if (!Asn1X509SetCrlEntries(pInfo->cCRLEntry, pInfo->rgCRLEntry,
|
|
&Crl.revokedCertificates))
|
|
goto ErrorReturn;
|
|
Crl.bit_mask |= revokedCertificates_present;
|
|
}
|
|
if (pInfo->cExtension) {
|
|
if (!Asn1X509SetExtensions(pInfo->cExtension, pInfo->rgExtension,
|
|
&Crl.crlExtensions))
|
|
goto ErrorReturn;
|
|
Crl.bit_mask |= crlExtensions_present;
|
|
}
|
|
|
|
fResult = Asn1InfoEncodeEx(
|
|
CertificateRevocationListToBeSigned_PDU,
|
|
&Crl,
|
|
dwFlags,
|
|
pEncodePara,
|
|
pvEncoded,
|
|
pcbEncoded
|
|
);
|
|
goto CommonReturn;
|
|
|
|
EncodeError:
|
|
SetLastError((DWORD) CRYPT_E_BAD_ENCODE);
|
|
ErrorReturn:
|
|
if (dwFlags & CRYPT_ENCODE_ALLOC_FLAG)
|
|
*((void **) pvEncoded) = NULL;
|
|
*pcbEncoded = 0;
|
|
fResult = FALSE;
|
|
CommonReturn:
|
|
Asn1X509FreeCrlEntries(&Crl.revokedCertificates);
|
|
Asn1X509FreeExtensions(&Crl.crlExtensions);
|
|
return fResult;
|
|
}
|
|
|
|
//+-------------------------------------------------------------------------
|
|
// Decode the CRL Info (ASN1 X509 ASN.1)
|
|
//--------------------------------------------------------------------------
|
|
BOOL WINAPI Asn1X509CrlInfoDecodeExCallback(
|
|
IN void *pvAsn1Info,
|
|
IN DWORD dwFlags,
|
|
IN OPTIONAL PCRYPT_DECODE_PARA pDecodePara,
|
|
OUT OPTIONAL void *pvStructInfo,
|
|
IN OUT LONG *plRemainExtra
|
|
)
|
|
{
|
|
BOOL fResult;
|
|
CertificateRevocationListToBeSigned *pCrl =
|
|
(CertificateRevocationListToBeSigned *) pvAsn1Info;
|
|
PCRL_INFO pInfo = (PCRL_INFO) pvStructInfo;
|
|
LONG lRemainExtra = *plRemainExtra;
|
|
BYTE *pbExtra;
|
|
|
|
lRemainExtra -= sizeof(CRL_INFO);
|
|
if (lRemainExtra < 0) {
|
|
pbExtra = NULL;
|
|
} else {
|
|
// Default all optional fields to zero
|
|
memset(pInfo, 0, sizeof(CRL_INFO));
|
|
|
|
// Update fields not needing extra memory after the CRL_INFO
|
|
if (pCrl->bit_mask &
|
|
CertificateRevocationListToBeSigned_version_present)
|
|
#ifdef OSS_CRYPT_ASN1
|
|
pInfo->dwVersion =
|
|
pCrl->CertificateRevocationListToBeSigned_version;
|
|
#else
|
|
pInfo->dwVersion = pCrl->version;
|
|
#endif // OSS_CRYPT_ASN1
|
|
if (!PkiAsn1FromChoiceOfTime(pCrl->thisUpdate.choice,
|
|
&pCrl->thisUpdate.u.generalTime,
|
|
&pCrl->thisUpdate.u.utcTime,
|
|
&pInfo->ThisUpdate))
|
|
goto DecodeError;
|
|
if (pCrl->bit_mask & nextUpdate_present) {
|
|
if (!PkiAsn1FromChoiceOfTime(pCrl->nextUpdate.choice,
|
|
&pCrl->nextUpdate.u.generalTime,
|
|
&pCrl->nextUpdate.u.utcTime,
|
|
&pInfo->NextUpdate))
|
|
goto DecodeError;
|
|
}
|
|
|
|
pbExtra = (BYTE *) pInfo + sizeof(CRL_INFO);
|
|
}
|
|
|
|
Asn1X509GetAlgorithm(&pCrl->signature, dwFlags,
|
|
&pInfo->SignatureAlgorithm, &pbExtra, &lRemainExtra);
|
|
Asn1X509GetAny(&pCrl->issuer, dwFlags,
|
|
&pInfo->Issuer, &pbExtra, &lRemainExtra);
|
|
if (pCrl->bit_mask & revokedCertificates_present)
|
|
Asn1X509GetCrlEntries(&pCrl->revokedCertificates, dwFlags,
|
|
&pInfo->cCRLEntry, &pInfo->rgCRLEntry, &pbExtra, &lRemainExtra);
|
|
if (pCrl->bit_mask & crlExtensions_present)
|
|
Asn1X509GetExtensions(&pCrl->crlExtensions, dwFlags,
|
|
&pInfo->cExtension, &pInfo->rgExtension, &pbExtra, &lRemainExtra);
|
|
|
|
fResult = TRUE;
|
|
CommonReturn:
|
|
*plRemainExtra = lRemainExtra;
|
|
return fResult;
|
|
|
|
ErrorReturn:
|
|
fResult = FALSE;
|
|
goto CommonReturn;
|
|
|
|
SET_ERROR(DecodeError, CRYPT_E_BAD_ENCODE)
|
|
}
|
|
|
|
BOOL WINAPI Asn1X509CrlInfoDecodeEx(
|
|
IN DWORD dwCertEncodingType,
|
|
IN LPCSTR lpszStructType,
|
|
IN const BYTE *pbEncoded,
|
|
IN DWORD cbEncoded,
|
|
IN DWORD dwFlags,
|
|
IN OPTIONAL PCRYPT_DECODE_PARA pDecodePara,
|
|
OUT OPTIONAL void *pvStructInfo,
|
|
IN OUT DWORD *pcbStructInfo
|
|
)
|
|
{
|
|
const BYTE *pbToBeSigned;
|
|
DWORD cbToBeSigned;
|
|
|
|
if ((dwFlags & CRYPT_DECODE_TO_BE_SIGNED_FLAG) ||
|
|
!Asn1UtilExtractCertificateToBeSignedContent(
|
|
pbEncoded,
|
|
cbEncoded,
|
|
&cbToBeSigned,
|
|
&pbToBeSigned
|
|
)) {
|
|
pbToBeSigned = pbEncoded;
|
|
cbToBeSigned = cbEncoded;
|
|
}
|
|
|
|
return Asn1InfoDecodeAndAllocEx(
|
|
CertificateRevocationListToBeSigned_PDU,
|
|
pbToBeSigned,
|
|
cbToBeSigned,
|
|
dwFlags,
|
|
pDecodePara,
|
|
Asn1X509CrlInfoDecodeExCallback,
|
|
pvStructInfo,
|
|
pcbStructInfo
|
|
);
|
|
}
|
|
|
|
//+-------------------------------------------------------------------------
|
|
// Encode the Cert Request Info (ASN1 X509 v3 ASN.1)
|
|
//--------------------------------------------------------------------------
|
|
BOOL WINAPI Asn1X509CertRequestInfoEncodeEx(
|
|
IN DWORD dwCertEncodingType,
|
|
IN LPCSTR lpszStructType,
|
|
IN PCERT_REQUEST_INFO pInfo,
|
|
IN DWORD dwFlags,
|
|
IN OPTIONAL PCRYPT_ENCODE_PARA pEncodePara,
|
|
OUT OPTIONAL void *pvEncoded,
|
|
IN OUT DWORD *pcbEncoded
|
|
)
|
|
{
|
|
BOOL fResult;
|
|
CertificationRequestInfo CertReq;
|
|
|
|
memset(&CertReq, 0, sizeof(CertReq));
|
|
CertReq.version = pInfo->dwVersion;
|
|
|
|
Asn1X509SetAny(&pInfo->Subject, &CertReq.subject);
|
|
if (!Asn1X509SetPublicKeyInfo(&pInfo->SubjectPublicKeyInfo,
|
|
&CertReq.subjectPublicKeyInfo))
|
|
goto ErrorReturn;
|
|
|
|
if (!Asn1X509SetAttributes(pInfo->cAttribute, pInfo->rgAttribute,
|
|
&CertReq.attributes))
|
|
goto ErrorReturn;
|
|
|
|
fResult = Asn1InfoEncodeEx(
|
|
CertificationRequestInfo_PDU,
|
|
&CertReq,
|
|
dwFlags,
|
|
pEncodePara,
|
|
pvEncoded,
|
|
pcbEncoded
|
|
);
|
|
goto CommonReturn;
|
|
|
|
ErrorReturn:
|
|
if (dwFlags & CRYPT_ENCODE_ALLOC_FLAG)
|
|
*((void **) pvEncoded) = NULL;
|
|
*pcbEncoded = 0;
|
|
fResult = FALSE;
|
|
CommonReturn:
|
|
Asn1X509FreeAttributes(&CertReq.attributes);
|
|
return fResult;
|
|
}
|
|
|
|
//+-------------------------------------------------------------------------
|
|
// Decode the Cert Request Info (ASN1 X509 v3 ASN.1)
|
|
//--------------------------------------------------------------------------
|
|
BOOL WINAPI Asn1X509CertRequestInfoDecodeExCallback(
|
|
IN void *pvAsn1Info,
|
|
IN DWORD dwFlags,
|
|
IN OPTIONAL PCRYPT_DECODE_PARA pDecodePara,
|
|
OUT OPTIONAL void *pvStructInfo,
|
|
IN OUT LONG *plRemainExtra
|
|
)
|
|
{
|
|
CertificationRequestInfoDecode *pCertReq =
|
|
(CertificationRequestInfoDecode *) pvAsn1Info;
|
|
PCERT_REQUEST_INFO pInfo = (PCERT_REQUEST_INFO) pvStructInfo;
|
|
BYTE *pbExtra;
|
|
LONG lRemainExtra = *plRemainExtra;
|
|
|
|
lRemainExtra -= sizeof(CERT_REQUEST_INFO);
|
|
if (lRemainExtra < 0) {
|
|
pbExtra = NULL;
|
|
} else {
|
|
// Default all optional fields to zero
|
|
memset(pInfo, 0, sizeof(CERT_REQUEST_INFO));
|
|
|
|
// Update fields not needing extra memory after the CERT_INFO
|
|
pInfo->dwVersion = pCertReq->version;
|
|
pbExtra = (BYTE *) pInfo + sizeof(CERT_REQUEST_INFO);
|
|
}
|
|
|
|
Asn1X509GetAny(&pCertReq->subject, dwFlags,
|
|
&pInfo->Subject, &pbExtra, &lRemainExtra);
|
|
Asn1X509GetPublicKeyInfo(&pCertReq->subjectPublicKeyInfo, dwFlags,
|
|
&pInfo->SubjectPublicKeyInfo,
|
|
&pbExtra, &lRemainExtra);
|
|
|
|
if (pCertReq->bit_mask & attributes_present) {
|
|
Asn1X509GetAttributes(&pCertReq->attributes, dwFlags,
|
|
&pInfo->cAttribute, &pInfo->rgAttribute, &pbExtra, &lRemainExtra);
|
|
}
|
|
|
|
*plRemainExtra = lRemainExtra;
|
|
return TRUE;
|
|
}
|
|
|
|
BOOL WINAPI Asn1X509CertRequestInfoDecodeEx(
|
|
IN DWORD dwCertEncodingType,
|
|
IN LPCSTR lpszStructType,
|
|
IN const BYTE *pbEncoded,
|
|
IN DWORD cbEncoded,
|
|
IN DWORD dwFlags,
|
|
IN OPTIONAL PCRYPT_DECODE_PARA pDecodePara,
|
|
OUT OPTIONAL void *pvStructInfo,
|
|
IN OUT DWORD *pcbStructInfo
|
|
)
|
|
{
|
|
const BYTE *pbToBeSigned;
|
|
DWORD cbToBeSigned;
|
|
|
|
if ((dwFlags & CRYPT_DECODE_TO_BE_SIGNED_FLAG) ||
|
|
!Asn1UtilExtractCertificateToBeSignedContent(
|
|
pbEncoded,
|
|
cbEncoded,
|
|
&cbToBeSigned,
|
|
&pbToBeSigned
|
|
)) {
|
|
pbToBeSigned = pbEncoded;
|
|
cbToBeSigned = cbEncoded;
|
|
}
|
|
|
|
return Asn1InfoDecodeAndAllocEx(
|
|
CertificationRequestInfoDecode_PDU,
|
|
pbToBeSigned,
|
|
cbToBeSigned,
|
|
dwFlags,
|
|
pDecodePara,
|
|
Asn1X509CertRequestInfoDecodeExCallback,
|
|
pvStructInfo,
|
|
pcbStructInfo
|
|
);
|
|
}
|
|
|
|
//+-------------------------------------------------------------------------
|
|
// Encode the Keygen Request Info (ASN1 X509 v3 ASN.1)
|
|
//--------------------------------------------------------------------------
|
|
BOOL WINAPI Asn1X509KeygenRequestInfoEncodeEx(
|
|
IN DWORD dwCertEncodingType,
|
|
IN LPCSTR lpszStructType,
|
|
IN PCERT_KEYGEN_REQUEST_INFO pInfo,
|
|
IN DWORD dwFlags,
|
|
IN OPTIONAL PCRYPT_ENCODE_PARA pEncodePara,
|
|
OUT OPTIONAL void *pvEncoded,
|
|
IN OUT DWORD *pcbEncoded
|
|
)
|
|
{
|
|
BOOL fResult;
|
|
KeygenRequestInfo KeygenReq;
|
|
DWORD dwErrLocation;
|
|
|
|
memset(&KeygenReq, 0, sizeof(KeygenReq));
|
|
|
|
if (!Asn1X509SetPublicKeyInfo(&pInfo->SubjectPublicKeyInfo,
|
|
&KeygenReq.subjectPublicKeyInfo))
|
|
goto ErrorReturn;
|
|
if (!Asn1X509SetUnicodeConvertedToIA5(pInfo->pwszChallengeString,
|
|
&KeygenReq.challenge, 0, &dwErrLocation)) {
|
|
*pcbEncoded = dwErrLocation;
|
|
goto InvalidIA5;
|
|
}
|
|
|
|
fResult = Asn1InfoEncodeEx(
|
|
KeygenRequestInfo_PDU,
|
|
&KeygenReq,
|
|
dwFlags,
|
|
pEncodePara,
|
|
pvEncoded,
|
|
pcbEncoded
|
|
);
|
|
goto CommonReturn;
|
|
|
|
ErrorReturn:
|
|
*pcbEncoded = 0;
|
|
InvalidIA5:
|
|
if (dwFlags & CRYPT_ENCODE_ALLOC_FLAG)
|
|
*((void **) pvEncoded) = NULL;
|
|
fResult = FALSE;
|
|
CommonReturn:
|
|
Asn1X509FreeUnicodeConvertedToIA5(&KeygenReq.challenge);
|
|
return fResult;
|
|
}
|
|
|
|
//+-------------------------------------------------------------------------
|
|
// Decode the Keygen Request Info (ASN1 X509 v3 ASN.1)
|
|
//--------------------------------------------------------------------------
|
|
BOOL WINAPI Asn1X509KeygenRequestInfoDecodeExCallback(
|
|
IN void *pvAsn1Info,
|
|
IN DWORD dwFlags,
|
|
IN OPTIONAL PCRYPT_DECODE_PARA pDecodePara,
|
|
OUT OPTIONAL void *pvStructInfo,
|
|
IN OUT LONG *plRemainExtra
|
|
)
|
|
{
|
|
KeygenRequestInfo *pKeygenReq = (KeygenRequestInfo *) pvAsn1Info;
|
|
PCERT_KEYGEN_REQUEST_INFO pInfo = (PCERT_KEYGEN_REQUEST_INFO) pvStructInfo;
|
|
LONG lRemainExtra = *plRemainExtra;
|
|
BYTE *pbExtra;
|
|
|
|
lRemainExtra -= sizeof(CERT_KEYGEN_REQUEST_INFO);
|
|
if (lRemainExtra < 0) {
|
|
pbExtra = NULL;
|
|
} else {
|
|
// Default all optional fields to zero
|
|
memset(pInfo, 0, sizeof(CERT_KEYGEN_REQUEST_INFO));
|
|
|
|
pbExtra = (BYTE *) pInfo + sizeof(CERT_KEYGEN_REQUEST_INFO);
|
|
}
|
|
|
|
Asn1X509GetPublicKeyInfo(&pKeygenReq->subjectPublicKeyInfo, dwFlags,
|
|
&pInfo->SubjectPublicKeyInfo, &pbExtra, &lRemainExtra);
|
|
Asn1X509GetIA5ConvertedToUnicode(&pKeygenReq->challenge, dwFlags,
|
|
&pInfo->pwszChallengeString, &pbExtra, &lRemainExtra);
|
|
|
|
*plRemainExtra = lRemainExtra;
|
|
return TRUE;
|
|
}
|
|
|
|
BOOL WINAPI Asn1X509KeygenRequestInfoDecodeEx(
|
|
IN DWORD dwCertEncodingType,
|
|
IN LPCSTR lpszStructType,
|
|
IN const BYTE *pbEncoded,
|
|
IN DWORD cbEncoded,
|
|
IN DWORD dwFlags,
|
|
IN OPTIONAL PCRYPT_DECODE_PARA pDecodePara,
|
|
OUT OPTIONAL void *pvStructInfo,
|
|
IN OUT DWORD *pcbStructInfo
|
|
)
|
|
{
|
|
const BYTE *pbToBeSigned;
|
|
DWORD cbToBeSigned;
|
|
|
|
if ((dwFlags & CRYPT_DECODE_TO_BE_SIGNED_FLAG) ||
|
|
!Asn1UtilExtractCertificateToBeSignedContent(
|
|
pbEncoded,
|
|
cbEncoded,
|
|
&cbToBeSigned,
|
|
&pbToBeSigned
|
|
)) {
|
|
pbToBeSigned = pbEncoded;
|
|
cbToBeSigned = cbEncoded;
|
|
}
|
|
|
|
return Asn1InfoDecodeAndAllocEx(
|
|
KeygenRequestInfo_PDU,
|
|
pbToBeSigned,
|
|
cbToBeSigned,
|
|
dwFlags,
|
|
pDecodePara,
|
|
Asn1X509KeygenRequestInfoDecodeExCallback,
|
|
pvStructInfo,
|
|
pcbStructInfo
|
|
);
|
|
}
|
|
|
|
//+-------------------------------------------------------------------------
|
|
// Encode the Signed Content (ASN1 X509)
|
|
//--------------------------------------------------------------------------
|
|
BOOL WINAPI Asn1X509SignedContentEncodeEx(
|
|
IN DWORD dwCertEncodingType,
|
|
IN LPCSTR lpszStructType,
|
|
IN PCERT_SIGNED_CONTENT_INFO pInfo,
|
|
IN DWORD dwFlags,
|
|
IN OPTIONAL PCRYPT_ENCODE_PARA pEncodePara,
|
|
OUT OPTIONAL void *pvEncoded,
|
|
IN OUT DWORD *pcbEncoded
|
|
)
|
|
{
|
|
BOOL fResult;
|
|
SignedContent Asn1SignedContent;
|
|
CRYPT_BIT_BLOB SignatureBlob;
|
|
BYTE *pbAllocSignature = NULL;
|
|
|
|
memset(&Asn1SignedContent, 0, sizeof(Asn1SignedContent));
|
|
Asn1X509SetAny(&pInfo->ToBeSigned, &Asn1SignedContent.toBeSigned);
|
|
if (!Asn1X509SetAlgorithm(&pInfo->SignatureAlgorithm,
|
|
&Asn1SignedContent.algorithm, CRYPT_SIGN_ALG_OID_GROUP_ID))
|
|
goto ErrorReturn;
|
|
|
|
if (dwFlags & CRYPT_ENCODE_NO_SIGNATURE_BYTE_REVERSAL_FLAG) {
|
|
SignatureBlob.pbData = pInfo->Signature.pbData;
|
|
} else {
|
|
if (NULL == (pbAllocSignature = PkiAsn1AllocAndReverseBytes(
|
|
pInfo->Signature.pbData, pInfo->Signature.cbData)))
|
|
goto ErrorReturn;
|
|
SignatureBlob.pbData = pbAllocSignature;
|
|
}
|
|
SignatureBlob.cbData = pInfo->Signature.cbData;
|
|
SignatureBlob.cUnusedBits = 0;
|
|
Asn1X509SetBit(&SignatureBlob, &Asn1SignedContent.signature);
|
|
|
|
fResult = Asn1InfoEncodeEx(
|
|
SignedContent_PDU,
|
|
&Asn1SignedContent,
|
|
dwFlags,
|
|
pEncodePara,
|
|
pvEncoded,
|
|
pcbEncoded
|
|
);
|
|
goto CommonReturn;
|
|
|
|
ErrorReturn:
|
|
if (dwFlags & CRYPT_ENCODE_ALLOC_FLAG)
|
|
*((void **) pvEncoded) = NULL;
|
|
*pcbEncoded = 0;
|
|
fResult = FALSE;
|
|
CommonReturn:
|
|
if (pbAllocSignature)
|
|
PkiAsn1Free(pbAllocSignature);
|
|
return fResult;
|
|
}
|
|
|
|
//+-------------------------------------------------------------------------
|
|
// Decode the Signed Content (ASN1 X509)
|
|
//--------------------------------------------------------------------------
|
|
BOOL WINAPI Asn1X509SignedContentDecodeExCallback(
|
|
IN void *pvAsn1Info,
|
|
IN DWORD dwFlags,
|
|
IN OPTIONAL PCRYPT_DECODE_PARA pDecodePara,
|
|
OUT OPTIONAL void *pvStructInfo,
|
|
IN OUT LONG *plRemainExtra
|
|
)
|
|
{
|
|
SignedContent *pSignedContent = (SignedContent *) pvAsn1Info;
|
|
PCERT_SIGNED_CONTENT_INFO pInfo = (PCERT_SIGNED_CONTENT_INFO) pvStructInfo;
|
|
LONG lRemainExtra = *plRemainExtra;
|
|
BYTE *pbExtra;
|
|
|
|
lRemainExtra -= sizeof(CERT_SIGNED_CONTENT_INFO);
|
|
if (lRemainExtra < 0) {
|
|
pbExtra = NULL;
|
|
} else
|
|
pbExtra = (BYTE *) pInfo + sizeof(CERT_SIGNED_CONTENT_INFO);
|
|
|
|
Asn1X509GetAny(&pSignedContent->toBeSigned, dwFlags,
|
|
&pInfo->ToBeSigned, &pbExtra, &lRemainExtra);
|
|
Asn1X509GetAlgorithm(&pSignedContent->algorithm, dwFlags,
|
|
&pInfo->SignatureAlgorithm, &pbExtra, &lRemainExtra);
|
|
// Since bits will be reversed, always need to make a copy (dwFlags = 0)
|
|
Asn1X509GetBit(&pSignedContent->signature, 0,
|
|
&pInfo->Signature, &pbExtra, &lRemainExtra);
|
|
if (lRemainExtra >= 0) {
|
|
if (0 == (dwFlags & CRYPT_DECODE_NO_SIGNATURE_BYTE_REVERSAL_FLAG))
|
|
PkiAsn1ReverseBytes(pInfo->Signature.pbData,
|
|
pInfo->Signature.cbData);
|
|
}
|
|
|
|
*plRemainExtra = lRemainExtra;
|
|
return TRUE;
|
|
}
|
|
|
|
BOOL WINAPI Asn1X509SignedContentDecodeEx(
|
|
IN DWORD dwCertEncodingType,
|
|
IN LPCSTR lpszStructType,
|
|
IN const BYTE *pbEncoded,
|
|
IN DWORD cbEncoded,
|
|
IN DWORD dwFlags,
|
|
IN OPTIONAL PCRYPT_DECODE_PARA pDecodePara,
|
|
OUT OPTIONAL void *pvStructInfo,
|
|
IN OUT DWORD *pcbStructInfo
|
|
)
|
|
{
|
|
return Asn1InfoDecodeAndAllocEx(
|
|
SignedContent_PDU,
|
|
pbEncoded,
|
|
cbEncoded,
|
|
dwFlags,
|
|
pDecodePara,
|
|
Asn1X509SignedContentDecodeExCallback,
|
|
pvStructInfo,
|
|
pcbStructInfo
|
|
);
|
|
}
|
|
|
|
//+-------------------------------------------------------------------------
|
|
// Encode the Name Info (ASN1 X509)
|
|
//--------------------------------------------------------------------------
|
|
BOOL WINAPI Asn1X509NameInfoEncodeEx(
|
|
IN DWORD dwCertEncodingType,
|
|
IN LPCSTR lpszStructType,
|
|
IN PCERT_NAME_INFO pInfo,
|
|
IN DWORD dwFlags,
|
|
IN OPTIONAL PCRYPT_ENCODE_PARA pEncodePara,
|
|
OUT OPTIONAL void *pvEncoded,
|
|
IN OUT DWORD *pcbEncoded
|
|
)
|
|
{
|
|
BOOL fResult;
|
|
DWORD cRDN, cAttr;
|
|
PCERT_RDN pRDN;
|
|
PCERT_RDN_ATTR pAttr;
|
|
Name Asn1Name;
|
|
RelativeDistinguishedName *pAsn1RDN = NULL;
|
|
AttributeTypeValue *pAsn1Attr = NULL;
|
|
|
|
cRDN = pInfo->cRDN;
|
|
pRDN = pInfo->rgRDN;
|
|
Asn1Name.count = cRDN;
|
|
Asn1Name.value = NULL;
|
|
if (cRDN > 0) {
|
|
pAsn1RDN =
|
|
(RelativeDistinguishedName *) PkiZeroAlloc(
|
|
cRDN * sizeof(RelativeDistinguishedName));
|
|
if (pAsn1RDN == NULL)
|
|
goto ErrorReturn;
|
|
Asn1Name.value = pAsn1RDN;
|
|
}
|
|
|
|
// Array of RDNs
|
|
for ( ; cRDN > 0; cRDN--, pRDN++, pAsn1RDN++) {
|
|
cAttr = pRDN->cRDNAttr;
|
|
pAttr = pRDN->rgRDNAttr;
|
|
pAsn1RDN->count = cAttr;
|
|
|
|
if (cAttr > 0) {
|
|
pAsn1Attr =
|
|
(AttributeTypeValue *) PkiZeroAlloc(cAttr *
|
|
sizeof(AttributeTypeValue));
|
|
if (pAsn1Attr == NULL)
|
|
goto ErrorReturn;
|
|
pAsn1RDN->value = pAsn1Attr;
|
|
}
|
|
|
|
// Array of attribute/values
|
|
for ( ; cAttr > 0; cAttr--, pAttr++, pAsn1Attr++) {
|
|
// We're now ready to encode the attribute/value stuff
|
|
if (!Asn1X509SetRDNAttribute(pAttr, pAsn1Attr))
|
|
goto ErrorReturn;
|
|
}
|
|
}
|
|
|
|
fResult = Asn1InfoEncodeEx(
|
|
Name_PDU,
|
|
&Asn1Name,
|
|
dwFlags,
|
|
pEncodePara,
|
|
pvEncoded,
|
|
pcbEncoded
|
|
);
|
|
goto CommonReturn;
|
|
|
|
ErrorReturn:
|
|
if (dwFlags & CRYPT_ENCODE_ALLOC_FLAG)
|
|
*((void **) pvEncoded) = NULL;
|
|
*pcbEncoded = 0;
|
|
fResult = FALSE;
|
|
CommonReturn:
|
|
if (Asn1Name.value) {
|
|
cRDN = Asn1Name.count;
|
|
pRDN = pInfo->rgRDN;
|
|
pAsn1RDN = Asn1Name.value;
|
|
for ( ; cRDN > 0; cRDN--, pRDN++, pAsn1RDN++) {
|
|
if (pAsn1RDN->value) {
|
|
cAttr = pAsn1RDN->count;
|
|
pAttr = pRDN->rgRDNAttr;
|
|
pAsn1Attr = pAsn1RDN->value;
|
|
for ( ; cAttr > 0; cAttr--, pAttr++, pAsn1Attr++)
|
|
Asn1X509FreeRDNAttribute(pAttr, pAsn1Attr);
|
|
PkiFree(pAsn1RDN->value);
|
|
}
|
|
}
|
|
PkiFree(Asn1Name.value);
|
|
}
|
|
return fResult;
|
|
}
|
|
|
|
//+-------------------------------------------------------------------------
|
|
// Decode the Name Info (ASN1 X509)
|
|
//--------------------------------------------------------------------------
|
|
BOOL WINAPI Asn1X509NameInfoDecodeExCallback(
|
|
IN void *pvAsn1Info,
|
|
IN DWORD dwFlags,
|
|
IN OPTIONAL PCRYPT_DECODE_PARA pDecodePara,
|
|
OUT OPTIONAL void *pvStructInfo,
|
|
IN OUT LONG *plRemainExtra
|
|
)
|
|
{
|
|
Name *pAsn1Name = (Name *) pvAsn1Info;
|
|
PCERT_NAME_INFO pInfo = (PCERT_NAME_INFO) pvStructInfo;
|
|
LONG lRemainExtra = *plRemainExtra;
|
|
BYTE *pbExtra;
|
|
LONG lAlignExtra;
|
|
|
|
DWORD cRDN, cAttr;
|
|
PCERT_RDN pRDN;
|
|
PCERT_RDN_ATTR pAttr;
|
|
RelativeDistinguishedName *pAsn1RDN;
|
|
AttributeTypeValue *pAsn1Attr;
|
|
|
|
lRemainExtra -= sizeof(CERT_NAME_INFO);
|
|
if (lRemainExtra < 0) {
|
|
pbExtra = NULL;
|
|
} else
|
|
pbExtra = (BYTE *) pInfo + sizeof(CERT_NAME_INFO);
|
|
|
|
cRDN = pAsn1Name->count;
|
|
pAsn1RDN = pAsn1Name->value;
|
|
lAlignExtra = INFO_LEN_ALIGN(cRDN * sizeof(CERT_RDN));
|
|
lRemainExtra -= lAlignExtra;
|
|
if (lRemainExtra >= 0) {
|
|
pInfo->cRDN = cRDN;
|
|
pRDN = (PCERT_RDN) pbExtra;
|
|
pInfo->rgRDN = pRDN;
|
|
pbExtra += lAlignExtra;
|
|
} else
|
|
pRDN = NULL;
|
|
|
|
// Array of RDNs
|
|
for (; cRDN > 0; cRDN--, pRDN++, pAsn1RDN++) {
|
|
cAttr = pAsn1RDN->count;
|
|
pAsn1Attr = pAsn1RDN->value;
|
|
lAlignExtra = INFO_LEN_ALIGN(cAttr * sizeof(CERT_RDN_ATTR));
|
|
lRemainExtra -= lAlignExtra;
|
|
if (lRemainExtra >= 0) {
|
|
pRDN->cRDNAttr = cAttr;
|
|
pAttr = (PCERT_RDN_ATTR) pbExtra;
|
|
pRDN->rgRDNAttr = pAttr;
|
|
pbExtra += lAlignExtra;
|
|
} else
|
|
pAttr = NULL;
|
|
|
|
// Array of attribute/values
|
|
for (; cAttr > 0; cAttr--, pAttr++, pAsn1Attr++)
|
|
// We're now ready to decode the attribute/value stuff
|
|
if (!Asn1X509GetRDNAttribute(pAsn1Attr, dwFlags,
|
|
pAttr, &pbExtra, &lRemainExtra))
|
|
return FALSE;
|
|
}
|
|
|
|
*plRemainExtra = lRemainExtra;
|
|
return TRUE;
|
|
}
|
|
|
|
|
|
BOOL WINAPI Asn1X509NameInfoDecodeEx(
|
|
IN DWORD dwCertEncodingType,
|
|
IN LPCSTR lpszStructType,
|
|
IN const BYTE *pbEncoded,
|
|
IN DWORD cbEncoded,
|
|
IN DWORD dwFlags,
|
|
IN OPTIONAL PCRYPT_DECODE_PARA pDecodePara,
|
|
OUT OPTIONAL void *pvStructInfo,
|
|
IN OUT DWORD *pcbStructInfo
|
|
)
|
|
{
|
|
return Asn1InfoDecodeAndAllocEx(
|
|
Name_PDU,
|
|
pbEncoded,
|
|
cbEncoded,
|
|
dwFlags,
|
|
pDecodePara,
|
|
Asn1X509NameInfoDecodeExCallback,
|
|
pvStructInfo,
|
|
pcbStructInfo
|
|
);
|
|
}
|
|
|
|
|
|
//+-------------------------------------------------------------------------
|
|
// Encode a single Name Value (ASN1 X509)
|
|
//--------------------------------------------------------------------------
|
|
BOOL WINAPI Asn1X509NameValueEncodeEx(
|
|
IN DWORD dwCertEncodingType,
|
|
IN LPCSTR lpszStructType,
|
|
IN PCERT_NAME_VALUE pInfo,
|
|
IN DWORD dwFlags,
|
|
IN OPTIONAL PCRYPT_ENCODE_PARA pEncodePara,
|
|
OUT OPTIONAL void *pvEncoded,
|
|
IN OUT DWORD *pcbEncoded
|
|
)
|
|
{
|
|
BOOL fResult;
|
|
DWORD dwValueType;
|
|
|
|
if (dwFlags & CRYPT_ENCODE_ALLOC_FLAG)
|
|
*((void **) pvEncoded) = NULL;
|
|
|
|
dwValueType = pInfo->dwValueType;
|
|
switch (dwValueType) {
|
|
case CERT_RDN_ANY_TYPE:
|
|
SetLastError((DWORD) E_INVALIDARG);
|
|
*pcbEncoded = 0;
|
|
fResult = FALSE;
|
|
break;
|
|
#ifndef ASN1_SUPPORTS_UTF8_TAG
|
|
case CERT_RDN_UTF8_STRING:
|
|
{
|
|
CERT_NAME_VALUE EncodedBlobInfo;
|
|
|
|
fResult = Asn1X509AllocAndEncodeUTF8(
|
|
&pInfo->Value,
|
|
&EncodedBlobInfo.Value.pbData,
|
|
&EncodedBlobInfo.Value.cbData
|
|
);
|
|
if (fResult) {
|
|
EncodedBlobInfo.dwValueType = CERT_RDN_ENCODED_BLOB;
|
|
fResult = Asn1X509NameValueEncodeEx(
|
|
dwCertEncodingType,
|
|
lpszStructType,
|
|
&EncodedBlobInfo,
|
|
dwFlags,
|
|
pEncodePara,
|
|
pvEncoded,
|
|
pcbEncoded
|
|
);
|
|
Asn1X509FreeEncodedUTF8(EncodedBlobInfo.Value.pbData);
|
|
} else
|
|
*pcbEncoded = 0;
|
|
}
|
|
break;
|
|
#endif // not defined ASN1_SUPPORTS_UTF8_TAG
|
|
case CERT_RDN_ENCODED_BLOB:
|
|
{
|
|
DWORD cbEncoded = pInfo->Value.cbData;
|
|
|
|
fResult = TRUE;
|
|
if (dwFlags & CRYPT_ENCODE_ALLOC_FLAG) {
|
|
if (cbEncoded) {
|
|
BYTE *pb;
|
|
PFN_CRYPT_ALLOC pfnAlloc =
|
|
PkiGetEncodeAllocFunction(pEncodePara);
|
|
if (NULL == (pb = (BYTE *) pfnAlloc(cbEncoded))) {
|
|
fResult = FALSE;
|
|
cbEncoded = 0;
|
|
} else {
|
|
memcpy(pb, pInfo->Value.pbData, cbEncoded);
|
|
*((BYTE **) pvEncoded) = pb;
|
|
}
|
|
}
|
|
} else {
|
|
if (NULL == pvEncoded)
|
|
*pcbEncoded = 0;
|
|
if (*pcbEncoded < cbEncoded) {
|
|
if (pvEncoded) {
|
|
SetLastError((DWORD) ERROR_MORE_DATA);
|
|
fResult = FALSE;
|
|
}
|
|
} else if (cbEncoded)
|
|
memcpy((BYTE *) pvEncoded, pInfo->Value.pbData, cbEncoded);
|
|
}
|
|
*pcbEncoded = cbEncoded;
|
|
}
|
|
break;
|
|
default:
|
|
{
|
|
AnyString Asn1AnyString;
|
|
|
|
Asn1X509SetAnyString(dwValueType, &pInfo->Value, &Asn1AnyString);
|
|
fResult = Asn1InfoEncodeEx(
|
|
AnyString_PDU,
|
|
&Asn1AnyString,
|
|
dwFlags,
|
|
pEncodePara,
|
|
pvEncoded,
|
|
pcbEncoded
|
|
);
|
|
}
|
|
break;
|
|
}
|
|
return fResult;
|
|
}
|
|
|
|
//+-------------------------------------------------------------------------
|
|
// Decode a single Name Value (ASN1 X509)
|
|
//--------------------------------------------------------------------------
|
|
BOOL WINAPI Asn1X509NameValueDecodeEx(
|
|
IN DWORD dwCertEncodingType,
|
|
IN LPCSTR lpszStructType,
|
|
IN const BYTE *pbEncoded,
|
|
IN DWORD cbEncoded,
|
|
IN DWORD dwFlags,
|
|
IN OPTIONAL PCRYPT_DECODE_PARA pDecodePara,
|
|
OUT OPTIONAL void *pvStructInfo,
|
|
IN OUT DWORD *pcbStructInfo
|
|
)
|
|
{
|
|
BOOL fResult;
|
|
PCERT_NAME_VALUE pInfo = (PCERT_NAME_VALUE) pvStructInfo;
|
|
NOCOPYANY Asn1Value;
|
|
BYTE *pbExtra;
|
|
LONG lRemainExtra;
|
|
|
|
|
|
if (pInfo == NULL || (dwFlags & CRYPT_DECODE_ALLOC_FLAG))
|
|
*pcbStructInfo = 0;
|
|
|
|
memset(&Asn1Value, 0, sizeof(Asn1Value));
|
|
Asn1Value.encoded = (void *)pbEncoded;
|
|
Asn1Value.length = cbEncoded;
|
|
|
|
// for lRemainExtra < 0, LENGTH_ONLY calculation
|
|
lRemainExtra = (LONG) *pcbStructInfo - sizeof(CERT_NAME_VALUE);
|
|
if (lRemainExtra < 0) {
|
|
pbExtra = NULL;
|
|
} else
|
|
pbExtra = (BYTE *) pInfo + sizeof(CERT_NAME_VALUE);
|
|
|
|
if (!Asn1X509GetRDNAttributeValue(&Asn1Value, dwFlags,
|
|
&pInfo->dwValueType, &pInfo->Value, &pbExtra, &lRemainExtra))
|
|
goto GetRDNAttributeValueError;
|
|
|
|
if (dwFlags & CRYPT_DECODE_ALLOC_FLAG) {
|
|
PCERT_NAME_VALUE pAllocInfo;
|
|
PFN_CRYPT_ALLOC pfnAlloc = PkiGetDecodeAllocFunction(pDecodePara);
|
|
|
|
assert(0 > lRemainExtra);
|
|
lRemainExtra = -lRemainExtra;
|
|
|
|
pAllocInfo = (PCERT_NAME_VALUE) pfnAlloc(lRemainExtra);
|
|
*((PCERT_NAME_VALUE *) pvStructInfo) = pAllocInfo;
|
|
if (NULL == pAllocInfo)
|
|
goto OutOfMemory;
|
|
*pcbStructInfo = lRemainExtra;
|
|
|
|
pbExtra = (BYTE *) pAllocInfo + sizeof(CERT_NAME_VALUE);
|
|
lRemainExtra -= sizeof(CERT_NAME_VALUE);
|
|
if (!Asn1X509GetRDNAttributeValue(&Asn1Value, dwFlags,
|
|
&pAllocInfo->dwValueType, &pAllocInfo->Value,
|
|
&pbExtra, &lRemainExtra))
|
|
goto GetRDNAttributeValueError;
|
|
assert(lRemainExtra >= 0);
|
|
}
|
|
|
|
if (lRemainExtra >= 0)
|
|
*pcbStructInfo = *pcbStructInfo - (DWORD) lRemainExtra;
|
|
else {
|
|
*pcbStructInfo = *pcbStructInfo + (DWORD) -lRemainExtra;
|
|
if (pInfo) goto LengthError;
|
|
}
|
|
|
|
fResult = TRUE;
|
|
goto CommonReturn;
|
|
|
|
LengthError:
|
|
SetLastError((DWORD) ERROR_MORE_DATA);
|
|
fResult = FALSE;
|
|
CommonReturn:
|
|
return fResult;
|
|
|
|
ErrorReturn:
|
|
fResult = FALSE;
|
|
*pcbStructInfo = 0;
|
|
goto CommonReturn;
|
|
TRACE_ERROR(GetRDNAttributeValueError)
|
|
TRACE_ERROR(OutOfMemory)
|
|
}
|
|
|
|
//+-------------------------------------------------------------------------
|
|
// Encode X509 certificate extensions (ASN1)
|
|
//--------------------------------------------------------------------------
|
|
BOOL WINAPI Asn1X509ExtensionsEncodeEx(
|
|
IN DWORD dwCertEncodingType,
|
|
IN LPCSTR lpszStructType,
|
|
IN PCERT_EXTENSIONS pInfo,
|
|
IN DWORD dwFlags,
|
|
IN OPTIONAL PCRYPT_ENCODE_PARA pEncodePara,
|
|
OUT OPTIONAL void *pvEncoded,
|
|
IN OUT DWORD *pcbEncoded
|
|
)
|
|
{
|
|
BOOL fResult;
|
|
Extensions Asn1Ext;
|
|
|
|
if (!Asn1X509SetExtensions(pInfo->cExtension, pInfo->rgExtension, &Asn1Ext))
|
|
goto ErrorReturn;
|
|
|
|
fResult = Asn1InfoEncodeEx(
|
|
Extensions_PDU,
|
|
&Asn1Ext,
|
|
dwFlags,
|
|
pEncodePara,
|
|
pvEncoded,
|
|
pcbEncoded
|
|
);
|
|
goto CommonReturn;
|
|
|
|
ErrorReturn:
|
|
if (dwFlags & CRYPT_ENCODE_ALLOC_FLAG)
|
|
*((void **) pvEncoded) = NULL;
|
|
*pcbEncoded = 0;
|
|
fResult = FALSE;
|
|
CommonReturn:
|
|
Asn1X509FreeExtensions(&Asn1Ext);
|
|
return fResult;
|
|
}
|
|
|
|
//+-------------------------------------------------------------------------
|
|
// Decode X509 certificate extensions (ASN1)
|
|
//--------------------------------------------------------------------------
|
|
BOOL WINAPI Asn1X509ExtensionsDecodeExCallback(
|
|
IN void *pvAsn1Info,
|
|
IN DWORD dwFlags,
|
|
IN OPTIONAL PCRYPT_DECODE_PARA pDecodePara,
|
|
OUT OPTIONAL void *pvStructInfo,
|
|
IN OUT LONG *plRemainExtra
|
|
)
|
|
{
|
|
Extensions *pAsn1Ext = (Extensions *) pvAsn1Info;
|
|
PCERT_EXTENSIONS pInfo = (PCERT_EXTENSIONS) pvStructInfo;
|
|
LONG lRemainExtra = *plRemainExtra;
|
|
BYTE *pbExtra;
|
|
|
|
lRemainExtra -= sizeof(CERT_EXTENSIONS);
|
|
if (lRemainExtra < 0) {
|
|
pbExtra = NULL;
|
|
} else
|
|
pbExtra = (BYTE *) pInfo + sizeof(CERT_EXTENSIONS);
|
|
|
|
Asn1X509GetExtensions(pAsn1Ext, dwFlags,
|
|
&pInfo->cExtension, &pInfo->rgExtension, &pbExtra, &lRemainExtra);
|
|
|
|
*plRemainExtra = lRemainExtra;
|
|
return TRUE;
|
|
}
|
|
|
|
#define T61_ASN_TAG 0x14
|
|
|
|
BOOL WINAPI Asn1X509ExtensionsDecodeEx(
|
|
IN DWORD dwCertEncodingType,
|
|
IN LPCSTR lpszStructType,
|
|
IN const BYTE *pbEncoded,
|
|
IN DWORD cbEncoded,
|
|
IN DWORD dwFlags,
|
|
IN OPTIONAL PCRYPT_DECODE_PARA pDecodePara,
|
|
OUT OPTIONAL void *pvStructInfo,
|
|
IN OUT DWORD *pcbStructInfo
|
|
)
|
|
{
|
|
|
|
if (0 < cbEncoded && T61_ASN_TAG == *pbEncoded) {
|
|
// Entrust wraps X509 Extensions within a T61 string
|
|
DWORD cbContent;
|
|
const BYTE *pbContent;
|
|
|
|
// Skip past the outer T61 tag and length octets
|
|
if (0 < Asn1UtilExtractContent(
|
|
pbEncoded,
|
|
cbEncoded,
|
|
&cbContent,
|
|
&pbContent
|
|
)) {
|
|
cbEncoded = cbContent;
|
|
pbEncoded = pbContent;
|
|
}
|
|
}
|
|
|
|
return Asn1InfoDecodeAndAllocEx(
|
|
Extensions_PDU,
|
|
pbEncoded,
|
|
cbEncoded,
|
|
dwFlags,
|
|
pDecodePara,
|
|
Asn1X509ExtensionsDecodeExCallback,
|
|
pvStructInfo,
|
|
pcbStructInfo
|
|
);
|
|
}
|
|
|
|
//+-------------------------------------------------------------------------
|
|
// Public Key Info Encode (ASN1 X509)
|
|
//--------------------------------------------------------------------------
|
|
BOOL WINAPI Asn1X509PublicKeyInfoEncodeEx(
|
|
IN DWORD dwCertEncodingType,
|
|
IN LPCSTR lpszStructType,
|
|
IN PCERT_PUBLIC_KEY_INFO pInfo,
|
|
IN DWORD dwFlags,
|
|
IN OPTIONAL PCRYPT_ENCODE_PARA pEncodePara,
|
|
OUT OPTIONAL void *pvEncoded,
|
|
IN OUT DWORD *pcbEncoded
|
|
)
|
|
{
|
|
BOOL fResult;
|
|
SubjectPublicKeyInfo PublicKey;
|
|
|
|
if (!Asn1X509SetPublicKeyInfo(pInfo, &PublicKey))
|
|
goto ErrorReturn;
|
|
|
|
fResult = Asn1InfoEncodeEx(
|
|
SubjectPublicKeyInfo_PDU,
|
|
&PublicKey,
|
|
dwFlags,
|
|
pEncodePara,
|
|
pvEncoded,
|
|
pcbEncoded
|
|
);
|
|
goto CommonReturn;
|
|
|
|
ErrorReturn:
|
|
if (dwFlags & CRYPT_ENCODE_ALLOC_FLAG)
|
|
*((void **) pvEncoded) = NULL;
|
|
*pcbEncoded = 0;
|
|
fResult = FALSE;
|
|
CommonReturn:
|
|
return fResult;
|
|
}
|
|
|
|
|
|
//+-------------------------------------------------------------------------
|
|
// Public Key Info Decode (ASN1 X509)
|
|
//--------------------------------------------------------------------------
|
|
BOOL WINAPI Asn1X509PublicKeyInfoDecodeExCallback(
|
|
IN void *pvAsn1Info,
|
|
IN DWORD dwFlags,
|
|
IN OPTIONAL PCRYPT_DECODE_PARA pDecodePara,
|
|
OUT OPTIONAL void *pvStructInfo,
|
|
IN OUT LONG *plRemainExtra
|
|
)
|
|
{
|
|
SubjectPublicKeyInfo *pPublicKey = (SubjectPublicKeyInfo *) pvAsn1Info;
|
|
PCERT_PUBLIC_KEY_INFO pInfo = (PCERT_PUBLIC_KEY_INFO) pvStructInfo;
|
|
LONG lRemainExtra = *plRemainExtra;
|
|
BYTE *pbExtra;
|
|
|
|
lRemainExtra -= sizeof(CERT_PUBLIC_KEY_INFO);
|
|
if (lRemainExtra < 0) {
|
|
pbExtra = NULL;
|
|
} else
|
|
pbExtra = (BYTE *) pInfo + sizeof(CERT_PUBLIC_KEY_INFO);
|
|
|
|
Asn1X509GetPublicKeyInfo(pPublicKey, dwFlags,
|
|
pInfo, &pbExtra, &lRemainExtra);
|
|
|
|
*plRemainExtra = lRemainExtra;
|
|
return TRUE;
|
|
}
|
|
|
|
BOOL WINAPI Asn1X509PublicKeyInfoDecodeEx(
|
|
IN DWORD dwCertEncodingType,
|
|
IN LPCSTR lpszStructType,
|
|
IN const BYTE *pbEncoded,
|
|
IN DWORD cbEncoded,
|
|
IN DWORD dwFlags,
|
|
IN OPTIONAL PCRYPT_DECODE_PARA pDecodePara,
|
|
OUT OPTIONAL void *pvStructInfo,
|
|
IN OUT DWORD *pcbStructInfo
|
|
)
|
|
{
|
|
return Asn1InfoDecodeAndAllocEx(
|
|
SubjectPublicKeyInfo_PDU,
|
|
pbEncoded,
|
|
cbEncoded,
|
|
dwFlags,
|
|
pDecodePara,
|
|
Asn1X509PublicKeyInfoDecodeExCallback,
|
|
pvStructInfo,
|
|
pcbStructInfo
|
|
);
|
|
}
|
|
|
|
|
|
#ifndef RSA1
|
|
#define RSA1 ((DWORD)'R'+((DWORD)'S'<<8)+((DWORD)'A'<<16)+((DWORD)'1'<<24))
|
|
#endif
|
|
|
|
//+-------------------------------------------------------------------------
|
|
// RSA Public Key Structure Encode (ASN1 X509)
|
|
//
|
|
// Converts from the CAPI public key representation to a PKCS #1 RSAPublicKey
|
|
//
|
|
// BYTE reversal::
|
|
// - this only needs to be done for little endian processors
|
|
//--------------------------------------------------------------------------
|
|
BOOL WINAPI Asn1RSAPublicKeyStrucEncodeEx(
|
|
IN DWORD dwCertEncodingType,
|
|
IN LPCSTR lpszStructType,
|
|
IN PUBLICKEYSTRUC *pPubKeyStruc,
|
|
IN DWORD dwFlags,
|
|
IN OPTIONAL PCRYPT_ENCODE_PARA pEncodePara,
|
|
OUT OPTIONAL void *pvEncoded,
|
|
IN OUT DWORD *pcbEncoded
|
|
)
|
|
{
|
|
BOOL fResult;
|
|
BYTE *pbKeyBlob;
|
|
RSAPUBKEY *pRsaPubKey;
|
|
const BYTE *pbModulus;
|
|
DWORD cbModulus;
|
|
BYTE *pbAllocModulus = NULL;
|
|
RSAPublicKey Asn1PubKey;
|
|
|
|
// The CAPI public key representation consists of the following sequence:
|
|
// - PUBLICKEYSTRUC
|
|
// - RSAPUBKEY
|
|
// - rgbModulus[]
|
|
pbKeyBlob = (BYTE *) pPubKeyStruc;
|
|
pRsaPubKey = (RSAPUBKEY *) (pbKeyBlob + sizeof(PUBLICKEYSTRUC));
|
|
pbModulus = pbKeyBlob + sizeof(PUBLICKEYSTRUC) + sizeof(RSAPUBKEY);
|
|
cbModulus = pRsaPubKey->bitlen / 8;
|
|
|
|
assert(cbModulus > 0);
|
|
assert(pPubKeyStruc->bType == PUBLICKEYBLOB);
|
|
assert(pPubKeyStruc->bVersion == CUR_BLOB_VERSION);
|
|
assert(pPubKeyStruc->aiKeyAlg == CALG_RSA_SIGN ||
|
|
pPubKeyStruc->aiKeyAlg == CALG_RSA_KEYX);
|
|
assert(pRsaPubKey->magic == RSA1);
|
|
assert(pRsaPubKey->bitlen % 8 == 0);
|
|
|
|
if (pPubKeyStruc->bType != PUBLICKEYBLOB)
|
|
goto InvalidArg;
|
|
|
|
// PKCS #1 ASN.1 encode
|
|
//
|
|
// ASN1 isn't reversing HUGE_INTEGERs. Also, after doing the
|
|
// reversal insert a leading 0 byte to force it to always be treated
|
|
// as an unsigned integer
|
|
if (NULL == (pbAllocModulus = (BYTE *) PkiNonzeroAlloc(cbModulus + 1)))
|
|
goto ErrorReturn;
|
|
*pbAllocModulus = 0;
|
|
memcpy(pbAllocModulus + 1, pbModulus, cbModulus);
|
|
PkiAsn1ReverseBytes(pbAllocModulus + 1, cbModulus);
|
|
pbModulus = pbAllocModulus;
|
|
cbModulus++;
|
|
|
|
Asn1PubKey.publicExponent = pRsaPubKey->pubexp;
|
|
Asn1PubKey.modulus.length = cbModulus;
|
|
Asn1PubKey.modulus.value = (BYTE *) pbModulus;
|
|
|
|
fResult = Asn1InfoEncodeEx(
|
|
RSAPublicKey_PDU,
|
|
&Asn1PubKey,
|
|
dwFlags,
|
|
pEncodePara,
|
|
pvEncoded,
|
|
pcbEncoded
|
|
);
|
|
goto CommonReturn;
|
|
|
|
InvalidArg:
|
|
SetLastError((DWORD) E_INVALIDARG);
|
|
ErrorReturn:
|
|
if (dwFlags & CRYPT_ENCODE_ALLOC_FLAG)
|
|
*((void **) pvEncoded) = NULL;
|
|
*pcbEncoded = 0;
|
|
fResult = FALSE;
|
|
CommonReturn:
|
|
if (pbAllocModulus)
|
|
PkiFree(pbAllocModulus);
|
|
return fResult;
|
|
}
|
|
|
|
|
|
//+-------------------------------------------------------------------------
|
|
// RSA Public Key Structure Decode (ASN1 X509)
|
|
//
|
|
// Converts from a PKCS #1 RSAPublicKey to a CAPI public key representation
|
|
//
|
|
// BYTE reversal::
|
|
// - this only needs to be done for little endian processors
|
|
//--------------------------------------------------------------------------
|
|
BOOL WINAPI Asn1RSAPublicKeyStrucDecodeExCallback(
|
|
IN void *pvAsn1Info,
|
|
IN DWORD dwFlags,
|
|
IN OPTIONAL PCRYPT_DECODE_PARA pDecodePara,
|
|
OUT OPTIONAL void *pvStructInfo,
|
|
IN OUT LONG *plRemainExtra
|
|
)
|
|
{
|
|
RSAPublicKey *pAsn1PubKey = (RSAPublicKey *) pvAsn1Info;
|
|
PUBLICKEYSTRUC *pPubKeyStruc = (PUBLICKEYSTRUC *) pvStructInfo;
|
|
BYTE *pbAsn1Modulus;
|
|
DWORD cbModulus;
|
|
|
|
// Now convert the ASN1 RSA public key into CAPI's representation which
|
|
// consists of the following sequence:
|
|
// - PUBLICKEYSTRUC
|
|
// - RSAPUBKEY
|
|
// - rgbModulus[]
|
|
cbModulus = pAsn1PubKey->modulus.length;
|
|
pbAsn1Modulus = pAsn1PubKey->modulus.value;
|
|
// Strip off a leading 0 byte. Its there in the decoded ASN
|
|
// integer for an unsigned integer with the leading bit set.
|
|
if (cbModulus > 1 && *pbAsn1Modulus == 0) {
|
|
pbAsn1Modulus++;
|
|
cbModulus--;
|
|
}
|
|
*plRemainExtra -= sizeof(PUBLICKEYSTRUC) + sizeof(RSAPUBKEY) + cbModulus;
|
|
if (0 <= *plRemainExtra) {
|
|
BYTE *pbKeyBlob = (BYTE *) pPubKeyStruc;
|
|
RSAPUBKEY *pRsaPubKey =
|
|
(RSAPUBKEY *) (pbKeyBlob + sizeof(PUBLICKEYSTRUC));
|
|
BYTE *pbModulus = pbKeyBlob + sizeof(PUBLICKEYSTRUC) +
|
|
sizeof(RSAPUBKEY);
|
|
|
|
pPubKeyStruc->bType = PUBLICKEYBLOB;
|
|
pPubKeyStruc->bVersion = CUR_BLOB_VERSION;
|
|
pPubKeyStruc->reserved = 0;
|
|
// Note: KEYX can also be used for doing a signature
|
|
pPubKeyStruc->aiKeyAlg = CALG_RSA_KEYX;
|
|
pRsaPubKey->magic = RSA1;
|
|
pRsaPubKey->bitlen = cbModulus * 8;
|
|
pRsaPubKey->pubexp = pAsn1PubKey->publicExponent;
|
|
if (cbModulus > 0) {
|
|
memcpy(pbModulus, pbAsn1Modulus, cbModulus);
|
|
// ASN1 isn't reversing HUGEINTEGERs
|
|
PkiAsn1ReverseBytes(pbModulus, cbModulus);
|
|
}
|
|
}
|
|
return TRUE;
|
|
}
|
|
|
|
BOOL WINAPI Asn1RSAPublicKeyStrucDecodeEx(
|
|
IN DWORD dwCertEncodingType,
|
|
IN LPCSTR lpszStructType,
|
|
IN const BYTE *pbEncoded,
|
|
IN DWORD cbEncoded,
|
|
IN DWORD dwFlags,
|
|
IN OPTIONAL PCRYPT_DECODE_PARA pDecodePara,
|
|
OUT OPTIONAL void *pvStructInfo,
|
|
IN OUT DWORD *pcbStructInfo
|
|
)
|
|
{
|
|
return Asn1InfoDecodeAndAllocEx(
|
|
RSAPublicKey_PDU,
|
|
pbEncoded,
|
|
cbEncoded,
|
|
dwFlags,
|
|
pDecodePara,
|
|
Asn1RSAPublicKeyStrucDecodeExCallback,
|
|
pvStructInfo,
|
|
pcbStructInfo
|
|
);
|
|
}
|
|
|
|
//+-------------------------------------------------------------------------
|
|
// Authority Key Id Extension Encode (ASN1 X509)
|
|
//--------------------------------------------------------------------------
|
|
BOOL WINAPI Asn1X509AuthorityKeyIdEncodeEx(
|
|
IN DWORD dwCertEncodingType,
|
|
IN LPCSTR lpszStructType,
|
|
IN PCERT_AUTHORITY_KEY_ID_INFO pInfo,
|
|
IN DWORD dwFlags,
|
|
IN OPTIONAL PCRYPT_ENCODE_PARA pEncodePara,
|
|
OUT OPTIONAL void *pvEncoded,
|
|
IN OUT DWORD *pcbEncoded
|
|
)
|
|
{
|
|
BOOL fResult;
|
|
|
|
AuthorityKeyId Asn1AuthorityKeyId;
|
|
memset(&Asn1AuthorityKeyId, 0, sizeof(Asn1AuthorityKeyId));
|
|
|
|
if (pInfo->KeyId.cbData) {
|
|
Asn1X509SetOctetString(&pInfo->KeyId,
|
|
#ifdef OSS_CRYPT_ASN1
|
|
&Asn1AuthorityKeyId.AuthorityKeyId_keyIdentifier);
|
|
#else
|
|
&Asn1AuthorityKeyId.keyIdentifier);
|
|
#endif // OSS_CRYPT_ASN1
|
|
Asn1AuthorityKeyId.bit_mask |= AuthorityKeyId_keyIdentifier_present;
|
|
}
|
|
if (pInfo->CertIssuer.cbData) {
|
|
Asn1X509SetAny(&pInfo->CertIssuer, &Asn1AuthorityKeyId.certIssuer);
|
|
Asn1AuthorityKeyId.bit_mask |= certIssuer_present;
|
|
}
|
|
if (pInfo->CertSerialNumber.cbData) {
|
|
if (!Asn1X509SetHugeInteger(&pInfo->CertSerialNumber,
|
|
&Asn1AuthorityKeyId.certSerialNumber))
|
|
goto ErrorReturn;
|
|
Asn1AuthorityKeyId.bit_mask |= certSerialNumber_present;
|
|
}
|
|
|
|
fResult = Asn1InfoEncodeEx(
|
|
AuthorityKeyId_PDU,
|
|
&Asn1AuthorityKeyId,
|
|
dwFlags,
|
|
pEncodePara,
|
|
pvEncoded,
|
|
pcbEncoded
|
|
);
|
|
|
|
goto CommonReturn;
|
|
|
|
ErrorReturn:
|
|
if (dwFlags & CRYPT_ENCODE_ALLOC_FLAG)
|
|
*((void **) pvEncoded) = NULL;
|
|
*pcbEncoded = 0;
|
|
fResult = FALSE;
|
|
CommonReturn:
|
|
Asn1X509FreeHugeInteger(&Asn1AuthorityKeyId.certSerialNumber);
|
|
return fResult;
|
|
}
|
|
|
|
//+-------------------------------------------------------------------------
|
|
// Authority Key Id Extension Decode (ASN1 X509)
|
|
//--------------------------------------------------------------------------
|
|
BOOL WINAPI Asn1X509AuthorityKeyIdDecodeExCallback(
|
|
IN void *pvAsn1Info,
|
|
IN DWORD dwFlags,
|
|
IN OPTIONAL PCRYPT_DECODE_PARA pDecodePara,
|
|
OUT OPTIONAL void *pvStructInfo,
|
|
IN OUT LONG *plRemainExtra
|
|
)
|
|
{
|
|
AuthorityKeyId *pAuthorityKeyId = (AuthorityKeyId *) pvAsn1Info;
|
|
PCERT_AUTHORITY_KEY_ID_INFO pInfo =
|
|
(PCERT_AUTHORITY_KEY_ID_INFO) pvStructInfo;
|
|
LONG lRemainExtra = *plRemainExtra;
|
|
BYTE *pbExtra;
|
|
|
|
lRemainExtra -= sizeof(CERT_AUTHORITY_KEY_ID_INFO);
|
|
if (lRemainExtra < 0) {
|
|
pbExtra = NULL;
|
|
} else {
|
|
// Default all optional fields to zero
|
|
memset(pInfo, 0, sizeof(CERT_AUTHORITY_KEY_ID_INFO));
|
|
pbExtra = (BYTE *) pInfo + sizeof(CERT_AUTHORITY_KEY_ID_INFO);
|
|
}
|
|
|
|
if (pAuthorityKeyId->bit_mask & AuthorityKeyId_keyIdentifier_present)
|
|
#ifdef OSS_CRYPT_ASN1
|
|
Asn1X509GetOctetString(&pAuthorityKeyId->AuthorityKeyId_keyIdentifier,
|
|
#else
|
|
Asn1X509GetOctetString(&pAuthorityKeyId->keyIdentifier,
|
|
#endif // OSS_CRYPT_ASN1
|
|
dwFlags, &pInfo->KeyId, &pbExtra, &lRemainExtra);
|
|
if (pAuthorityKeyId->bit_mask & certIssuer_present)
|
|
Asn1X509GetAny(&pAuthorityKeyId->certIssuer, dwFlags,
|
|
&pInfo->CertIssuer, &pbExtra, &lRemainExtra);
|
|
if (pAuthorityKeyId->bit_mask & certSerialNumber_present)
|
|
Asn1X509GetHugeInteger(&pAuthorityKeyId->certSerialNumber, dwFlags,
|
|
&pInfo->CertSerialNumber, &pbExtra, &lRemainExtra);
|
|
|
|
*plRemainExtra = lRemainExtra;
|
|
return TRUE;
|
|
}
|
|
|
|
BOOL WINAPI Asn1X509AuthorityKeyIdDecodeEx(
|
|
IN DWORD dwCertEncodingType,
|
|
IN LPCSTR lpszStructType,
|
|
IN const BYTE *pbEncoded,
|
|
IN DWORD cbEncoded,
|
|
IN DWORD dwFlags,
|
|
IN OPTIONAL PCRYPT_DECODE_PARA pDecodePara,
|
|
OUT OPTIONAL void *pvStructInfo,
|
|
IN OUT DWORD *pcbStructInfo
|
|
)
|
|
{
|
|
return Asn1InfoDecodeAndAllocEx(
|
|
AuthorityKeyId_PDU,
|
|
pbEncoded,
|
|
cbEncoded,
|
|
dwFlags,
|
|
pDecodePara,
|
|
Asn1X509AuthorityKeyIdDecodeExCallback,
|
|
pvStructInfo,
|
|
pcbStructInfo
|
|
);
|
|
}
|
|
|
|
//+-------------------------------------------------------------------------
|
|
// Authority Key Id2 Extension Encode (ASN1 X509)
|
|
//--------------------------------------------------------------------------
|
|
BOOL WINAPI Asn1X509AuthorityKeyId2EncodeEx(
|
|
IN DWORD dwCertEncodingType,
|
|
IN LPCSTR lpszStructType,
|
|
IN PCERT_AUTHORITY_KEY_ID2_INFO pInfo,
|
|
IN DWORD dwFlags,
|
|
IN OPTIONAL PCRYPT_ENCODE_PARA pEncodePara,
|
|
OUT OPTIONAL void *pvEncoded,
|
|
IN OUT DWORD *pcbEncoded
|
|
)
|
|
{
|
|
BOOL fResult;
|
|
DWORD dwErrLocation;
|
|
|
|
AuthorityKeyId2 Asn1AuthorityKeyId2;
|
|
memset(&Asn1AuthorityKeyId2, 0, sizeof(Asn1AuthorityKeyId2));
|
|
|
|
if (pInfo->KeyId.cbData) {
|
|
Asn1X509SetOctetString(&pInfo->KeyId,
|
|
#ifdef OSS_CRYPT_ASN1
|
|
&Asn1AuthorityKeyId2.AuthorityKeyId2_keyIdentifier);
|
|
#else
|
|
&Asn1AuthorityKeyId2.keyIdentifier);
|
|
#endif // OSS_CRYPT_ASN1
|
|
Asn1AuthorityKeyId2.bit_mask |= AuthorityKeyId2_keyIdentifier_present;
|
|
}
|
|
if (pInfo->AuthorityCertIssuer.cAltEntry) {
|
|
if (!Asn1X509SetAltNames(&pInfo->AuthorityCertIssuer,
|
|
&Asn1AuthorityKeyId2.authorityCertIssuer, 0, &dwErrLocation)) {
|
|
*pcbEncoded = dwErrLocation;
|
|
goto AltNamesError;
|
|
}
|
|
Asn1AuthorityKeyId2.bit_mask |= authorityCertIssuer_present;
|
|
}
|
|
if (pInfo->AuthorityCertSerialNumber.cbData) {
|
|
if (!Asn1X509SetHugeInteger(&pInfo->AuthorityCertSerialNumber,
|
|
&Asn1AuthorityKeyId2.authorityCertSerialNumber))
|
|
goto ErrorReturn;
|
|
Asn1AuthorityKeyId2.bit_mask |= authorityCertSerialNumber_present;
|
|
}
|
|
|
|
fResult = Asn1InfoEncodeEx(
|
|
AuthorityKeyId2_PDU,
|
|
&Asn1AuthorityKeyId2,
|
|
dwFlags,
|
|
pEncodePara,
|
|
pvEncoded,
|
|
pcbEncoded
|
|
);
|
|
|
|
goto CommonReturn;
|
|
|
|
ErrorReturn:
|
|
if (dwFlags & CRYPT_ENCODE_ALLOC_FLAG)
|
|
*((void **) pvEncoded) = NULL;
|
|
*pcbEncoded = 0;
|
|
AltNamesError:
|
|
fResult = FALSE;
|
|
CommonReturn:
|
|
Asn1X509FreeAltNames(&Asn1AuthorityKeyId2.authorityCertIssuer);
|
|
Asn1X509FreeHugeInteger(&Asn1AuthorityKeyId2.authorityCertSerialNumber);
|
|
return fResult;
|
|
}
|
|
|
|
//+-------------------------------------------------------------------------
|
|
// Authority Key Id2 Extension Decode (ASN1 X509)
|
|
//--------------------------------------------------------------------------
|
|
BOOL WINAPI Asn1X509AuthorityKeyId2DecodeExCallback(
|
|
IN void *pvAsn1Info,
|
|
IN DWORD dwFlags,
|
|
IN OPTIONAL PCRYPT_DECODE_PARA pDecodePara,
|
|
OUT OPTIONAL void *pvStructInfo,
|
|
IN OUT LONG *plRemainExtra
|
|
)
|
|
{
|
|
BOOL fResult;
|
|
AuthorityKeyId2 *pAuthorityKeyId2 = (AuthorityKeyId2 *) pvAsn1Info;
|
|
PCERT_AUTHORITY_KEY_ID2_INFO pInfo =
|
|
(PCERT_AUTHORITY_KEY_ID2_INFO) pvStructInfo;
|
|
LONG lRemainExtra = *plRemainExtra;
|
|
BYTE *pbExtra;
|
|
|
|
lRemainExtra -= sizeof(CERT_AUTHORITY_KEY_ID2_INFO);
|
|
if (lRemainExtra < 0) {
|
|
pbExtra = NULL;
|
|
} else {
|
|
// Default all optional fields to zero
|
|
memset(pInfo, 0, sizeof(CERT_AUTHORITY_KEY_ID2_INFO));
|
|
pbExtra = (BYTE *) pInfo + sizeof(CERT_AUTHORITY_KEY_ID2_INFO);
|
|
}
|
|
|
|
if (pAuthorityKeyId2->bit_mask & AuthorityKeyId2_keyIdentifier_present)
|
|
#ifdef OSS_CRYPT_ASN1
|
|
Asn1X509GetOctetString(&pAuthorityKeyId2->AuthorityKeyId2_keyIdentifier,
|
|
#else
|
|
Asn1X509GetOctetString(&pAuthorityKeyId2->keyIdentifier,
|
|
#endif // OSS_CRYPT_ASN1
|
|
dwFlags, &pInfo->KeyId, &pbExtra, &lRemainExtra);
|
|
if (pAuthorityKeyId2->bit_mask & authorityCertIssuer_present) {
|
|
if (!Asn1X509GetAltNames(&pAuthorityKeyId2->authorityCertIssuer, dwFlags,
|
|
&pInfo->AuthorityCertIssuer, &pbExtra, &lRemainExtra))
|
|
goto ErrorReturn;
|
|
}
|
|
if (pAuthorityKeyId2->bit_mask & authorityCertSerialNumber_present)
|
|
Asn1X509GetHugeInteger(&pAuthorityKeyId2->authorityCertSerialNumber, dwFlags,
|
|
&pInfo->AuthorityCertSerialNumber, &pbExtra, &lRemainExtra);
|
|
|
|
fResult = TRUE;
|
|
CommonReturn:
|
|
*plRemainExtra = lRemainExtra;
|
|
return fResult;
|
|
|
|
ErrorReturn:
|
|
fResult = FALSE;
|
|
goto CommonReturn;
|
|
}
|
|
|
|
BOOL WINAPI Asn1X509AuthorityKeyId2DecodeEx(
|
|
IN DWORD dwCertEncodingType,
|
|
IN LPCSTR lpszStructType,
|
|
IN const BYTE *pbEncoded,
|
|
IN DWORD cbEncoded,
|
|
IN DWORD dwFlags,
|
|
IN OPTIONAL PCRYPT_DECODE_PARA pDecodePara,
|
|
OUT OPTIONAL void *pvStructInfo,
|
|
IN OUT DWORD *pcbStructInfo
|
|
)
|
|
{
|
|
return Asn1InfoDecodeAndAllocEx(
|
|
AuthorityKeyId2_PDU,
|
|
pbEncoded,
|
|
cbEncoded,
|
|
dwFlags,
|
|
pDecodePara,
|
|
Asn1X509AuthorityKeyId2DecodeExCallback,
|
|
pvStructInfo,
|
|
pcbStructInfo
|
|
);
|
|
}
|
|
|
|
|
|
//+-------------------------------------------------------------------------
|
|
// Key Attributes Extension Encode (ASN1 X509)
|
|
//--------------------------------------------------------------------------
|
|
BOOL WINAPI Asn1X509KeyAttributesEncodeEx(
|
|
IN DWORD dwCertEncodingType,
|
|
IN LPCSTR lpszStructType,
|
|
IN PCERT_KEY_ATTRIBUTES_INFO pInfo,
|
|
IN DWORD dwFlags,
|
|
IN OPTIONAL PCRYPT_ENCODE_PARA pEncodePara,
|
|
OUT OPTIONAL void *pvEncoded,
|
|
IN OUT DWORD *pcbEncoded
|
|
)
|
|
{
|
|
BOOL fResult;
|
|
KeyAttributes Asn1KeyAttributes;
|
|
memset(&Asn1KeyAttributes, 0, sizeof(Asn1KeyAttributes));
|
|
|
|
if (pInfo->KeyId.cbData) {
|
|
Asn1X509SetOctetString(&pInfo->KeyId,
|
|
#ifdef OSS_CRYPT_ASN1
|
|
&Asn1KeyAttributes.KeyAttributes_keyIdentifier);
|
|
#else
|
|
&Asn1KeyAttributes.keyIdentifier);
|
|
#endif // OSS_CRYPT_ASN1
|
|
Asn1KeyAttributes.bit_mask |= KeyAttributes_keyIdentifier_present;
|
|
}
|
|
if (pInfo->IntendedKeyUsage.cbData) {
|
|
Asn1X509SetBitWithoutTrailingZeroes(&pInfo->IntendedKeyUsage,
|
|
&Asn1KeyAttributes.intendedKeyUsage);
|
|
Asn1KeyAttributes.bit_mask |= intendedKeyUsage_present;
|
|
}
|
|
if (pInfo->pPrivateKeyUsagePeriod) {
|
|
if (!PkiAsn1ToGeneralizedTime(
|
|
&pInfo->pPrivateKeyUsagePeriod->NotBefore,
|
|
&Asn1KeyAttributes.privateKeyUsagePeriod.notBefore))
|
|
goto EncodeError;
|
|
if (!PkiAsn1ToGeneralizedTime(
|
|
&pInfo->pPrivateKeyUsagePeriod->NotAfter,
|
|
&Asn1KeyAttributes.privateKeyUsagePeriod.notAfter))
|
|
goto EncodeError;
|
|
Asn1KeyAttributes.privateKeyUsagePeriod.bit_mask |=
|
|
notBefore_present | notAfter_present;
|
|
Asn1KeyAttributes.bit_mask |= privateKeyUsagePeriod_present;
|
|
}
|
|
|
|
fResult = Asn1InfoEncodeEx(
|
|
KeyAttributes_PDU,
|
|
&Asn1KeyAttributes,
|
|
dwFlags,
|
|
pEncodePara,
|
|
pvEncoded,
|
|
pcbEncoded
|
|
);
|
|
goto CommonReturn;
|
|
|
|
EncodeError:
|
|
SetLastError((DWORD) CRYPT_E_BAD_ENCODE);
|
|
if (dwFlags & CRYPT_ENCODE_ALLOC_FLAG)
|
|
*((void **) pvEncoded) = NULL;
|
|
*pcbEncoded = 0;
|
|
fResult = FALSE;
|
|
CommonReturn:
|
|
return fResult;
|
|
}
|
|
|
|
//+-------------------------------------------------------------------------
|
|
// Key Attributes Extension Decode (ASN1 X509)
|
|
//--------------------------------------------------------------------------
|
|
BOOL WINAPI Asn1X509KeyAttributesDecodeExCallback(
|
|
IN void *pvAsn1Info,
|
|
IN DWORD dwFlags,
|
|
IN OPTIONAL PCRYPT_DECODE_PARA pDecodePara,
|
|
OUT OPTIONAL void *pvStructInfo,
|
|
IN OUT LONG *plRemainExtra
|
|
)
|
|
{
|
|
BOOL fResult;
|
|
KeyAttributes *pKeyAttributes = (KeyAttributes *) pvAsn1Info;
|
|
PCERT_KEY_ATTRIBUTES_INFO pInfo = (PCERT_KEY_ATTRIBUTES_INFO) pvStructInfo;
|
|
LONG lRemainExtra = *plRemainExtra;
|
|
BYTE *pbExtra;
|
|
|
|
lRemainExtra -= sizeof(CERT_KEY_ATTRIBUTES_INFO);
|
|
if (lRemainExtra < 0) {
|
|
pbExtra = NULL;
|
|
} else {
|
|
// Default all optional fields to zero
|
|
memset(pInfo, 0, sizeof(CERT_KEY_ATTRIBUTES_INFO));
|
|
pbExtra = (BYTE *) pInfo + sizeof(CERT_KEY_ATTRIBUTES_INFO);
|
|
}
|
|
|
|
if (pKeyAttributes->bit_mask & KeyAttributes_keyIdentifier_present)
|
|
#ifdef OSS_CRYPT_ASN1
|
|
Asn1X509GetOctetString(&pKeyAttributes->KeyAttributes_keyIdentifier,
|
|
#else
|
|
Asn1X509GetOctetString(&pKeyAttributes->keyIdentifier,
|
|
#endif // OSS_CRYPT_ASN1
|
|
dwFlags, &pInfo->KeyId, &pbExtra, &lRemainExtra);
|
|
if (pKeyAttributes->bit_mask & intendedKeyUsage_present)
|
|
Asn1X509GetBit(&pKeyAttributes->intendedKeyUsage, dwFlags,
|
|
&pInfo->IntendedKeyUsage, &pbExtra, &lRemainExtra);
|
|
|
|
if (pKeyAttributes->bit_mask & privateKeyUsagePeriod_present) {
|
|
LONG lAlignExtra;
|
|
PrivateKeyValidity *pAsn1KeyUsage =
|
|
&pKeyAttributes->privateKeyUsagePeriod;
|
|
|
|
lAlignExtra = INFO_LEN_ALIGN(sizeof(CERT_PRIVATE_KEY_VALIDITY));
|
|
lRemainExtra -= lAlignExtra;
|
|
if (lRemainExtra >= 0) {
|
|
PCERT_PRIVATE_KEY_VALIDITY pKeyUsage =
|
|
(PCERT_PRIVATE_KEY_VALIDITY) pbExtra;
|
|
|
|
// Default all optional fields to zero
|
|
memset(pKeyUsage, 0, sizeof(CERT_PRIVATE_KEY_VALIDITY));
|
|
if (pAsn1KeyUsage->bit_mask & notBefore_present) {
|
|
if (!PkiAsn1FromGeneralizedTime(&pAsn1KeyUsage->notBefore,
|
|
&pKeyUsage->NotBefore))
|
|
goto DecodeError;
|
|
}
|
|
if (pAsn1KeyUsage->bit_mask & notAfter_present) {
|
|
if (!PkiAsn1FromGeneralizedTime(&pAsn1KeyUsage->notAfter,
|
|
&pKeyUsage->NotAfter))
|
|
goto DecodeError;
|
|
}
|
|
pInfo->pPrivateKeyUsagePeriod = pKeyUsage;
|
|
pbExtra += lAlignExtra;
|
|
}
|
|
}
|
|
|
|
fResult = TRUE;
|
|
CommonReturn:
|
|
*plRemainExtra = lRemainExtra;
|
|
return fResult;
|
|
|
|
ErrorReturn:
|
|
fResult = FALSE;
|
|
goto CommonReturn;
|
|
|
|
SET_ERROR(DecodeError, CRYPT_E_BAD_ENCODE)
|
|
}
|
|
|
|
BOOL WINAPI Asn1X509KeyAttributesDecodeEx(
|
|
IN DWORD dwCertEncodingType,
|
|
IN LPCSTR lpszStructType,
|
|
IN const BYTE *pbEncoded,
|
|
IN DWORD cbEncoded,
|
|
IN DWORD dwFlags,
|
|
IN OPTIONAL PCRYPT_DECODE_PARA pDecodePara,
|
|
OUT OPTIONAL void *pvStructInfo,
|
|
IN OUT DWORD *pcbStructInfo
|
|
)
|
|
{
|
|
return Asn1InfoDecodeAndAllocEx(
|
|
KeyAttributes_PDU,
|
|
pbEncoded,
|
|
cbEncoded,
|
|
dwFlags,
|
|
pDecodePara,
|
|
Asn1X509KeyAttributesDecodeExCallback,
|
|
pvStructInfo,
|
|
pcbStructInfo
|
|
);
|
|
}
|
|
|
|
|
|
//+-------------------------------------------------------------------------
|
|
// AltName Extension Encode (ASN1 X509)
|
|
//--------------------------------------------------------------------------
|
|
BOOL WINAPI Asn1X509AltNameEncodeEx(
|
|
IN DWORD dwCertEncodingType,
|
|
IN LPCSTR lpszStructType,
|
|
IN PCERT_ALT_NAME_INFO pInfo,
|
|
IN DWORD dwFlags,
|
|
IN OPTIONAL PCRYPT_ENCODE_PARA pEncodePara,
|
|
OUT OPTIONAL void *pvEncoded,
|
|
IN OUT DWORD *pcbEncoded
|
|
)
|
|
{
|
|
BOOL fResult;
|
|
AltNames AltNames;
|
|
DWORD dwErrLocation;
|
|
|
|
if (!Asn1X509SetAltNames(pInfo, &AltNames, 0, &dwErrLocation)) {
|
|
*pcbEncoded = dwErrLocation;
|
|
fResult = FALSE;
|
|
if (dwFlags & CRYPT_ENCODE_ALLOC_FLAG)
|
|
*((void **) pvEncoded) = NULL;
|
|
goto CommonReturn;
|
|
}
|
|
|
|
fResult = Asn1InfoEncodeEx(
|
|
AltNames_PDU,
|
|
&AltNames,
|
|
dwFlags,
|
|
pEncodePara,
|
|
pvEncoded,
|
|
pcbEncoded
|
|
);
|
|
|
|
CommonReturn:
|
|
Asn1X509FreeAltNames(&AltNames);
|
|
return fResult;
|
|
}
|
|
|
|
|
|
//+-------------------------------------------------------------------------
|
|
// AltName Extension Decode (ASN1 X509)
|
|
//--------------------------------------------------------------------------
|
|
BOOL WINAPI Asn1X509AltNameDecodeExCallback(
|
|
IN void *pvAsn1Info,
|
|
IN DWORD dwFlags,
|
|
IN OPTIONAL PCRYPT_DECODE_PARA pDecodePara,
|
|
OUT OPTIONAL void *pvStructInfo,
|
|
IN OUT LONG *plRemainExtra
|
|
)
|
|
{
|
|
BOOL fResult;
|
|
AltNames *pAltNames = (AltNames *) pvAsn1Info;
|
|
PCERT_ALT_NAME_INFO pInfo = (PCERT_ALT_NAME_INFO) pvStructInfo;
|
|
LONG lRemainExtra = *plRemainExtra;
|
|
BYTE *pbExtra;
|
|
|
|
lRemainExtra -= sizeof(CERT_ALT_NAME_INFO);
|
|
if (lRemainExtra < 0) {
|
|
pbExtra = NULL;
|
|
} else
|
|
pbExtra = (BYTE *) pInfo + sizeof(CERT_ALT_NAME_INFO);
|
|
|
|
if (!Asn1X509GetAltNames(pAltNames, dwFlags,
|
|
pInfo, &pbExtra, &lRemainExtra))
|
|
goto ErrorReturn;
|
|
|
|
fResult = TRUE;
|
|
CommonReturn:
|
|
*plRemainExtra = lRemainExtra;
|
|
return fResult;
|
|
|
|
ErrorReturn:
|
|
fResult = FALSE;
|
|
goto CommonReturn;
|
|
}
|
|
|
|
BOOL WINAPI Asn1X509AltNameDecodeEx(
|
|
IN DWORD dwCertEncodingType,
|
|
IN LPCSTR lpszStructType,
|
|
IN const BYTE *pbEncoded,
|
|
IN DWORD cbEncoded,
|
|
IN DWORD dwFlags,
|
|
IN OPTIONAL PCRYPT_DECODE_PARA pDecodePara,
|
|
OUT OPTIONAL void *pvStructInfo,
|
|
IN OUT DWORD *pcbStructInfo
|
|
)
|
|
{
|
|
return Asn1InfoDecodeAndAllocEx(
|
|
AltNames_PDU,
|
|
pbEncoded,
|
|
cbEncoded,
|
|
dwFlags,
|
|
pDecodePara,
|
|
Asn1X509AltNameDecodeExCallback,
|
|
pvStructInfo,
|
|
pcbStructInfo
|
|
);
|
|
}
|
|
|
|
|
|
|
|
//+-------------------------------------------------------------------------
|
|
// Key Usage Restriction Extension Encode (ASN1 X509)
|
|
//--------------------------------------------------------------------------
|
|
BOOL WINAPI Asn1X509KeyUsageRestrictionEncodeEx(
|
|
IN DWORD dwCertEncodingType,
|
|
IN LPCSTR lpszStructType,
|
|
IN PCERT_KEY_USAGE_RESTRICTION_INFO pInfo,
|
|
IN DWORD dwFlags,
|
|
IN OPTIONAL PCRYPT_ENCODE_PARA pEncodePara,
|
|
OUT OPTIONAL void *pvEncoded,
|
|
IN OUT DWORD *pcbEncoded
|
|
)
|
|
{
|
|
BOOL fResult;
|
|
DWORD cPolicyId;
|
|
|
|
KeyUsageRestriction Asn1KeyUsageRestriction;
|
|
memset(&Asn1KeyUsageRestriction, 0, sizeof(Asn1KeyUsageRestriction));
|
|
|
|
cPolicyId = pInfo->cCertPolicyId;
|
|
if (cPolicyId) {
|
|
PCERT_POLICY_ID pPolicyId = pInfo->rgCertPolicyId;
|
|
CertPolicyId *pAsn1PolicyId =
|
|
(CertPolicyId *) PkiZeroAlloc(cPolicyId * sizeof(CertPolicyId));
|
|
if (pAsn1PolicyId == NULL) goto ErrorReturn;
|
|
Asn1KeyUsageRestriction.certPolicySet.count = cPolicyId;
|
|
Asn1KeyUsageRestriction.certPolicySet.value = pAsn1PolicyId;
|
|
|
|
for ( ; cPolicyId > 0; cPolicyId--, pPolicyId++, pAsn1PolicyId++) {
|
|
DWORD cElement = pPolicyId->cCertPolicyElementId;
|
|
if (cElement > 0) {
|
|
LPSTR *ppszElement = pPolicyId->rgpszCertPolicyElementId;
|
|
EncodedObjectID *pAsn1Element =
|
|
(EncodedObjectID *) PkiZeroAlloc(cElement * sizeof(EncodedObjectID));
|
|
if (pAsn1Element == NULL) goto ErrorReturn;
|
|
pAsn1PolicyId->count = cElement;
|
|
pAsn1PolicyId->value = pAsn1Element;
|
|
for ( ; cElement > 0; cElement--, ppszElement++, pAsn1Element++)
|
|
if (!Asn1X509SetEncodedObjId(*ppszElement, pAsn1Element))
|
|
goto ErrorReturn;
|
|
}
|
|
}
|
|
Asn1KeyUsageRestriction.bit_mask |= certPolicySet_present;
|
|
}
|
|
|
|
if (pInfo->RestrictedKeyUsage.cbData) {
|
|
Asn1X509SetBitWithoutTrailingZeroes(&pInfo->RestrictedKeyUsage,
|
|
&Asn1KeyUsageRestriction.restrictedKeyUsage);
|
|
Asn1KeyUsageRestriction.bit_mask |= restrictedKeyUsage_present;
|
|
}
|
|
|
|
fResult = Asn1InfoEncodeEx(
|
|
KeyUsageRestriction_PDU,
|
|
&Asn1KeyUsageRestriction,
|
|
dwFlags,
|
|
pEncodePara,
|
|
pvEncoded,
|
|
pcbEncoded
|
|
);
|
|
|
|
goto CommonReturn;
|
|
|
|
ErrorReturn:
|
|
if (dwFlags & CRYPT_ENCODE_ALLOC_FLAG)
|
|
*((void **) pvEncoded) = NULL;
|
|
*pcbEncoded = 0;
|
|
fResult = FALSE;
|
|
CommonReturn:
|
|
if (Asn1KeyUsageRestriction.certPolicySet.value) {
|
|
cPolicyId = Asn1KeyUsageRestriction.certPolicySet.count;
|
|
CertPolicyId *pAsn1PolicyId = Asn1KeyUsageRestriction.certPolicySet.value;
|
|
for ( ; cPolicyId > 0; cPolicyId--, pAsn1PolicyId++)
|
|
if (pAsn1PolicyId->value)
|
|
PkiFree(pAsn1PolicyId->value);
|
|
PkiFree(Asn1KeyUsageRestriction.certPolicySet.value);
|
|
}
|
|
return fResult;
|
|
}
|
|
|
|
//+-------------------------------------------------------------------------
|
|
// Key Usage Restriction Extension Decode (ASN1 X509)
|
|
//--------------------------------------------------------------------------
|
|
BOOL WINAPI Asn1X509KeyUsageRestrictionDecodeExCallback(
|
|
IN void *pvAsn1Info,
|
|
IN DWORD dwFlags,
|
|
IN OPTIONAL PCRYPT_DECODE_PARA pDecodePara,
|
|
OUT OPTIONAL void *pvStructInfo,
|
|
IN OUT LONG *plRemainExtra
|
|
)
|
|
{
|
|
KeyUsageRestriction *pKeyUsageRestriction =
|
|
(KeyUsageRestriction *) pvAsn1Info;
|
|
PCERT_KEY_USAGE_RESTRICTION_INFO pInfo =
|
|
(PCERT_KEY_USAGE_RESTRICTION_INFO) pvStructInfo;
|
|
LONG lRemainExtra = *plRemainExtra;
|
|
BYTE *pbExtra;
|
|
|
|
lRemainExtra -= sizeof(CERT_KEY_USAGE_RESTRICTION_INFO);
|
|
if (lRemainExtra < 0) {
|
|
pbExtra = NULL;
|
|
} else {
|
|
// Default all optional fields to zero
|
|
memset(pInfo, 0, sizeof(CERT_KEY_USAGE_RESTRICTION_INFO));
|
|
pbExtra = (BYTE *) pInfo + sizeof(CERT_KEY_USAGE_RESTRICTION_INFO);
|
|
}
|
|
|
|
if (pKeyUsageRestriction->bit_mask & certPolicySet_present) {
|
|
LONG lAlignExtra;
|
|
DWORD cPolicyId;
|
|
PCERT_POLICY_ID pPolicyId;
|
|
CertPolicyId *pAsn1PolicyId;
|
|
|
|
cPolicyId = pKeyUsageRestriction->certPolicySet.count;
|
|
lAlignExtra = INFO_LEN_ALIGN(cPolicyId * sizeof(CERT_POLICY_ID));
|
|
lRemainExtra -= lAlignExtra;
|
|
if (lRemainExtra >= 0) {
|
|
pInfo->cCertPolicyId = cPolicyId;
|
|
pPolicyId = (PCERT_POLICY_ID) pbExtra;
|
|
pInfo->rgCertPolicyId = pPolicyId;
|
|
pbExtra += lAlignExtra;
|
|
} else
|
|
pPolicyId = NULL;
|
|
|
|
pAsn1PolicyId = pKeyUsageRestriction->certPolicySet.value;
|
|
for ( ; cPolicyId > 0; cPolicyId--, pPolicyId++, pAsn1PolicyId++) {
|
|
DWORD cElement;
|
|
LPSTR *ppszElement;
|
|
EncodedObjectID *pAsn1Element;
|
|
|
|
cElement = pAsn1PolicyId->count;
|
|
lAlignExtra = INFO_LEN_ALIGN(cElement * sizeof(LPSTR *));
|
|
lRemainExtra -= lAlignExtra;
|
|
if (lRemainExtra >= 0) {
|
|
pPolicyId->cCertPolicyElementId = cElement;
|
|
ppszElement = (LPSTR *) pbExtra;
|
|
pPolicyId->rgpszCertPolicyElementId = ppszElement;
|
|
pbExtra += lAlignExtra;
|
|
} else
|
|
ppszElement = NULL;
|
|
|
|
pAsn1Element = pAsn1PolicyId->value;
|
|
for ( ; cElement > 0; cElement--, ppszElement++, pAsn1Element++)
|
|
Asn1X509GetEncodedObjId(pAsn1Element, dwFlags,
|
|
ppszElement, &pbExtra, &lRemainExtra);
|
|
}
|
|
}
|
|
|
|
if (pKeyUsageRestriction->bit_mask & restrictedKeyUsage_present)
|
|
Asn1X509GetBit(&pKeyUsageRestriction->restrictedKeyUsage, dwFlags,
|
|
&pInfo->RestrictedKeyUsage, &pbExtra, &lRemainExtra);
|
|
|
|
*plRemainExtra = lRemainExtra;
|
|
return TRUE;
|
|
}
|
|
|
|
BOOL WINAPI Asn1X509KeyUsageRestrictionDecodeEx(
|
|
IN DWORD dwCertEncodingType,
|
|
IN LPCSTR lpszStructType,
|
|
IN const BYTE *pbEncoded,
|
|
IN DWORD cbEncoded,
|
|
IN DWORD dwFlags,
|
|
IN OPTIONAL PCRYPT_DECODE_PARA pDecodePara,
|
|
OUT OPTIONAL void *pvStructInfo,
|
|
IN OUT DWORD *pcbStructInfo
|
|
)
|
|
{
|
|
return Asn1InfoDecodeAndAllocEx(
|
|
KeyUsageRestriction_PDU,
|
|
pbEncoded,
|
|
cbEncoded,
|
|
dwFlags,
|
|
pDecodePara,
|
|
Asn1X509KeyUsageRestrictionDecodeExCallback,
|
|
pvStructInfo,
|
|
pcbStructInfo
|
|
);
|
|
}
|
|
|
|
//+-------------------------------------------------------------------------
|
|
// Basic Constraints Extension Encode (ASN1 X509)
|
|
//--------------------------------------------------------------------------
|
|
BOOL WINAPI Asn1X509BasicConstraintsEncodeEx(
|
|
IN DWORD dwCertEncodingType,
|
|
IN LPCSTR lpszStructType,
|
|
IN PCERT_BASIC_CONSTRAINTS_INFO pInfo,
|
|
IN DWORD dwFlags,
|
|
IN OPTIONAL PCRYPT_ENCODE_PARA pEncodePara,
|
|
OUT OPTIONAL void *pvEncoded,
|
|
IN OUT DWORD *pcbEncoded
|
|
)
|
|
{
|
|
BOOL fResult;
|
|
DWORD cSubtrees;
|
|
|
|
BasicConstraints Asn1BasicConstraints;
|
|
memset(&Asn1BasicConstraints, 0, sizeof(Asn1BasicConstraints));
|
|
|
|
Asn1X509SetBitWithoutTrailingZeroes(&pInfo->SubjectType,
|
|
&Asn1BasicConstraints.subjectType);
|
|
if (pInfo->fPathLenConstraint) {
|
|
#ifdef OSS_CRYPT_ASN1
|
|
Asn1BasicConstraints.BasicConstraints_pathLenConstraint =
|
|
#else
|
|
Asn1BasicConstraints.pathLenConstraint =
|
|
#endif // OSS_CRYPT_ASN1
|
|
pInfo->dwPathLenConstraint;
|
|
Asn1BasicConstraints.bit_mask |=
|
|
BasicConstraints_pathLenConstraint_present;
|
|
}
|
|
cSubtrees = pInfo->cSubtreesConstraint;
|
|
if (cSubtrees) {
|
|
PCERT_NAME_BLOB pSubtrees = pInfo->rgSubtreesConstraint;
|
|
NOCOPYANY *pAsn1Subtrees =
|
|
(NOCOPYANY *) PkiZeroAlloc(
|
|
cSubtrees * sizeof(NOCOPYANY));
|
|
if (pAsn1Subtrees == NULL) goto ErrorReturn;
|
|
Asn1BasicConstraints.subtreesConstraint.count = cSubtrees;
|
|
Asn1BasicConstraints.subtreesConstraint.value = pAsn1Subtrees;
|
|
|
|
for ( ; cSubtrees > 0; cSubtrees--, pSubtrees++, pAsn1Subtrees++)
|
|
Asn1X509SetAny(pSubtrees, pAsn1Subtrees);
|
|
Asn1BasicConstraints.bit_mask |= subtreesConstraint_present;
|
|
}
|
|
|
|
fResult = Asn1InfoEncodeEx(
|
|
BasicConstraints_PDU,
|
|
&Asn1BasicConstraints,
|
|
dwFlags,
|
|
pEncodePara,
|
|
pvEncoded,
|
|
pcbEncoded
|
|
);
|
|
|
|
goto CommonReturn;
|
|
|
|
ErrorReturn:
|
|
if (dwFlags & CRYPT_ENCODE_ALLOC_FLAG)
|
|
*((void **) pvEncoded) = NULL;
|
|
*pcbEncoded = 0;
|
|
fResult = FALSE;
|
|
CommonReturn:
|
|
if (Asn1BasicConstraints.subtreesConstraint.value)
|
|
PkiFree(Asn1BasicConstraints.subtreesConstraint.value);
|
|
return fResult;
|
|
}
|
|
|
|
//+-------------------------------------------------------------------------
|
|
// Basic Constraints Extension Decode (ASN1 X509)
|
|
//--------------------------------------------------------------------------
|
|
BOOL WINAPI Asn1X509BasicConstraintsDecodeExCallback(
|
|
IN void *pvAsn1Info,
|
|
IN DWORD dwFlags,
|
|
IN OPTIONAL PCRYPT_DECODE_PARA pDecodePara,
|
|
OUT OPTIONAL void *pvStructInfo,
|
|
IN OUT LONG *plRemainExtra
|
|
)
|
|
{
|
|
BasicConstraints *pBasicConstraints = (BasicConstraints *) pvAsn1Info;
|
|
PCERT_BASIC_CONSTRAINTS_INFO pInfo =
|
|
(PCERT_BASIC_CONSTRAINTS_INFO) pvStructInfo;
|
|
LONG lRemainExtra = *plRemainExtra;
|
|
BYTE *pbExtra;
|
|
|
|
lRemainExtra -= sizeof(CERT_BASIC_CONSTRAINTS_INFO);
|
|
if (lRemainExtra < 0) {
|
|
pbExtra = NULL;
|
|
} else {
|
|
// Default all optional fields to zero
|
|
memset(pInfo, 0, sizeof(CERT_BASIC_CONSTRAINTS_INFO));
|
|
|
|
// Update fields not needing extra memory after the
|
|
// CERT_BASIC_CONSTRAINTS_INFO
|
|
if (pBasicConstraints->bit_mask &
|
|
BasicConstraints_pathLenConstraint_present) {
|
|
pInfo->fPathLenConstraint = TRUE;
|
|
pInfo->dwPathLenConstraint =
|
|
#ifdef OSS_CRYPT_ASN1
|
|
pBasicConstraints->BasicConstraints_pathLenConstraint;
|
|
#else
|
|
pBasicConstraints->pathLenConstraint;
|
|
#endif // OSS_CRYPT_ASN1
|
|
}
|
|
|
|
pbExtra = (BYTE *) pInfo + sizeof(CERT_BASIC_CONSTRAINTS_INFO);
|
|
}
|
|
|
|
Asn1X509GetBit(&pBasicConstraints->subjectType, dwFlags,
|
|
&pInfo->SubjectType, &pbExtra, &lRemainExtra);
|
|
|
|
if (pBasicConstraints->bit_mask & subtreesConstraint_present) {
|
|
LONG lAlignExtra;
|
|
DWORD cSubtrees;
|
|
PCERT_NAME_BLOB pSubtrees;
|
|
NOCOPYANY *pAsn1Subtrees;
|
|
|
|
cSubtrees = pBasicConstraints->subtreesConstraint.count;
|
|
lAlignExtra = INFO_LEN_ALIGN(cSubtrees * sizeof(CERT_NAME_BLOB));
|
|
lRemainExtra -= lAlignExtra;
|
|
if (lRemainExtra >= 0) {
|
|
pInfo->cSubtreesConstraint = cSubtrees;
|
|
pSubtrees = (PCERT_NAME_BLOB) pbExtra;
|
|
pInfo->rgSubtreesConstraint = pSubtrees;
|
|
pbExtra += lAlignExtra;
|
|
} else
|
|
pSubtrees = NULL;
|
|
|
|
pAsn1Subtrees = pBasicConstraints->subtreesConstraint.value;
|
|
for ( ; cSubtrees > 0; cSubtrees--, pSubtrees++, pAsn1Subtrees++)
|
|
Asn1X509GetAny(pAsn1Subtrees, dwFlags,
|
|
pSubtrees, &pbExtra, &lRemainExtra);
|
|
}
|
|
|
|
*plRemainExtra = lRemainExtra;
|
|
return TRUE;
|
|
}
|
|
|
|
BOOL WINAPI Asn1X509BasicConstraintsDecodeEx(
|
|
IN DWORD dwCertEncodingType,
|
|
IN LPCSTR lpszStructType,
|
|
IN const BYTE *pbEncoded,
|
|
IN DWORD cbEncoded,
|
|
IN DWORD dwFlags,
|
|
IN OPTIONAL PCRYPT_DECODE_PARA pDecodePara,
|
|
OUT OPTIONAL void *pvStructInfo,
|
|
IN OUT DWORD *pcbStructInfo
|
|
)
|
|
{
|
|
return Asn1InfoDecodeAndAllocEx(
|
|
BasicConstraints_PDU,
|
|
pbEncoded,
|
|
cbEncoded,
|
|
dwFlags,
|
|
pDecodePara,
|
|
Asn1X509BasicConstraintsDecodeExCallback,
|
|
pvStructInfo,
|
|
pcbStructInfo
|
|
);
|
|
}
|
|
|
|
//+-------------------------------------------------------------------------
|
|
// Basic Constraints #2 Extension Encode (ASN1 X509)
|
|
//--------------------------------------------------------------------------
|
|
BOOL WINAPI Asn1X509BasicConstraints2EncodeEx(
|
|
IN DWORD dwCertEncodingType,
|
|
IN LPCSTR lpszStructType,
|
|
IN PCERT_BASIC_CONSTRAINTS2_INFO pInfo,
|
|
IN DWORD dwFlags,
|
|
IN OPTIONAL PCRYPT_ENCODE_PARA pEncodePara,
|
|
OUT OPTIONAL void *pvEncoded,
|
|
IN OUT DWORD *pcbEncoded
|
|
)
|
|
{
|
|
BasicConstraints2 Asn1Info;
|
|
memset(&Asn1Info, 0, sizeof(Asn1Info));
|
|
|
|
if (pInfo->fCA) {
|
|
Asn1Info.cA = TRUE;
|
|
Asn1Info.bit_mask |= cA_present;
|
|
}
|
|
if (pInfo->fPathLenConstraint) {
|
|
#ifdef OSS_CRYPT_ASN1
|
|
Asn1Info.BasicConstraints2_pathLenConstraint =
|
|
#else
|
|
Asn1Info.pathLenConstraint =
|
|
#endif // OSS_CRYPT_ASN1
|
|
pInfo->dwPathLenConstraint;
|
|
Asn1Info.bit_mask |= BasicConstraints2_pathLenConstraint_present;
|
|
}
|
|
|
|
return Asn1InfoEncodeEx(
|
|
BasicConstraints2_PDU,
|
|
&Asn1Info,
|
|
dwFlags,
|
|
pEncodePara,
|
|
pvEncoded,
|
|
pcbEncoded
|
|
);
|
|
}
|
|
|
|
//+-------------------------------------------------------------------------
|
|
// Basic Constraints #2 Extension Decode (ASN1 X509)
|
|
//--------------------------------------------------------------------------
|
|
BOOL WINAPI Asn1X509BasicConstraints2DecodeExCallback(
|
|
IN void *pvAsn1Info,
|
|
IN DWORD dwFlags,
|
|
IN OPTIONAL PCRYPT_DECODE_PARA pDecodePara,
|
|
OUT OPTIONAL void *pvStructInfo,
|
|
IN OUT LONG *plRemainExtra
|
|
)
|
|
{
|
|
BasicConstraints2 *pAsn1Info = (BasicConstraints2 *) pvAsn1Info;
|
|
PCERT_BASIC_CONSTRAINTS2_INFO pInfo =
|
|
(PCERT_BASIC_CONSTRAINTS2_INFO) pvStructInfo;
|
|
|
|
*plRemainExtra -= sizeof(CERT_BASIC_CONSTRAINTS2_INFO);
|
|
if (*plRemainExtra >= 0) {
|
|
memset(pInfo, 0, sizeof(CERT_BASIC_CONSTRAINTS2_INFO));
|
|
|
|
if (pAsn1Info->bit_mask & cA_present)
|
|
pInfo->fCA = (BOOLEAN) pAsn1Info->cA;
|
|
|
|
if (pAsn1Info->bit_mask &
|
|
BasicConstraints2_pathLenConstraint_present) {
|
|
pInfo->fPathLenConstraint = TRUE;
|
|
pInfo->dwPathLenConstraint =
|
|
#ifdef OSS_CRYPT_ASN1
|
|
pAsn1Info->BasicConstraints2_pathLenConstraint;
|
|
#else
|
|
pAsn1Info->pathLenConstraint;
|
|
#endif // OSS_CRYPT_ASN1
|
|
}
|
|
}
|
|
return TRUE;
|
|
}
|
|
|
|
BOOL WINAPI Asn1X509BasicConstraints2DecodeEx(
|
|
IN DWORD dwCertEncodingType,
|
|
IN LPCSTR lpszStructType,
|
|
IN const BYTE *pbEncoded,
|
|
IN DWORD cbEncoded,
|
|
IN DWORD dwFlags,
|
|
IN OPTIONAL PCRYPT_DECODE_PARA pDecodePara,
|
|
OUT OPTIONAL void *pvStructInfo,
|
|
IN OUT DWORD *pcbStructInfo
|
|
)
|
|
{
|
|
return Asn1InfoDecodeAndAllocEx(
|
|
BasicConstraints2_PDU,
|
|
pbEncoded,
|
|
cbEncoded,
|
|
dwFlags,
|
|
pDecodePara,
|
|
Asn1X509BasicConstraints2DecodeExCallback,
|
|
pvStructInfo,
|
|
pcbStructInfo
|
|
);
|
|
}
|
|
|
|
|
|
//+-------------------------------------------------------------------------
|
|
// Bits Extension Encode (ASN1 X509)
|
|
//--------------------------------------------------------------------------
|
|
BOOL WINAPI Asn1X509BitsEncodeEx(
|
|
IN DWORD dwCertEncodingType,
|
|
IN LPCSTR lpszStructType,
|
|
IN PCRYPT_BIT_BLOB pInfo,
|
|
IN DWORD dwFlags,
|
|
IN OPTIONAL PCRYPT_ENCODE_PARA pEncodePara,
|
|
OUT OPTIONAL void *pvEncoded,
|
|
IN OUT DWORD *pcbEncoded
|
|
)
|
|
{
|
|
BITSTRING Asn1Info;
|
|
|
|
Asn1X509SetBit(pInfo, &Asn1Info);
|
|
return Asn1InfoEncodeEx(
|
|
Bits_PDU,
|
|
&Asn1Info,
|
|
dwFlags,
|
|
pEncodePara,
|
|
pvEncoded,
|
|
pcbEncoded
|
|
);
|
|
}
|
|
|
|
//+-------------------------------------------------------------------------
|
|
// Bits Extension Decode (ASN1 X509)
|
|
//--------------------------------------------------------------------------
|
|
BOOL WINAPI Asn1X509BitsDecodeExCallback(
|
|
IN void *pvAsn1Info,
|
|
IN DWORD dwFlags,
|
|
IN OPTIONAL PCRYPT_DECODE_PARA pDecodePara,
|
|
OUT OPTIONAL void *pvStructInfo,
|
|
IN OUT LONG *plRemainExtra
|
|
)
|
|
{
|
|
BITSTRING *pAsn1Info = (BITSTRING *) pvAsn1Info;
|
|
PCRYPT_BIT_BLOB pInfo = (PCRYPT_BIT_BLOB) pvStructInfo;
|
|
LONG lRemainExtra = *plRemainExtra;
|
|
BYTE *pbExtra;
|
|
|
|
lRemainExtra -= sizeof(CRYPT_BIT_BLOB);
|
|
if (lRemainExtra < 0) {
|
|
pbExtra = NULL;
|
|
} else
|
|
pbExtra = (BYTE *) pInfo + sizeof(CRYPT_BIT_BLOB);
|
|
|
|
Asn1X509GetBit(pAsn1Info, dwFlags, pInfo, &pbExtra, &lRemainExtra);
|
|
|
|
*plRemainExtra = lRemainExtra;
|
|
return TRUE;
|
|
}
|
|
|
|
BOOL WINAPI Asn1X509BitsDecodeEx(
|
|
IN DWORD dwCertEncodingType,
|
|
IN LPCSTR lpszStructType,
|
|
IN const BYTE *pbEncoded,
|
|
IN DWORD cbEncoded,
|
|
IN DWORD dwFlags,
|
|
IN OPTIONAL PCRYPT_DECODE_PARA pDecodePara,
|
|
OUT OPTIONAL void *pvStructInfo,
|
|
IN OUT DWORD *pcbStructInfo
|
|
)
|
|
{
|
|
return Asn1InfoDecodeAndAllocEx(
|
|
Bits_PDU,
|
|
pbEncoded,
|
|
cbEncoded,
|
|
dwFlags,
|
|
pDecodePara,
|
|
Asn1X509BitsDecodeExCallback,
|
|
pvStructInfo,
|
|
pcbStructInfo
|
|
);
|
|
}
|
|
|
|
//+-------------------------------------------------------------------------
|
|
// Bits Without Trailing Zeroes Extension Encode (ASN1 X509)
|
|
//--------------------------------------------------------------------------
|
|
BOOL WINAPI Asn1X509BitsWithoutTrailingZeroesEncodeEx(
|
|
IN DWORD dwCertEncodingType,
|
|
IN LPCSTR lpszStructType,
|
|
IN PCRYPT_BIT_BLOB pInfo,
|
|
IN DWORD dwFlags,
|
|
IN OPTIONAL PCRYPT_ENCODE_PARA pEncodePara,
|
|
OUT OPTIONAL void *pvEncoded,
|
|
IN OUT DWORD *pcbEncoded
|
|
)
|
|
{
|
|
BITSTRING Asn1Info;
|
|
|
|
Asn1X509SetBitWithoutTrailingZeroes(pInfo, &Asn1Info);
|
|
return Asn1InfoEncodeEx(
|
|
Bits_PDU,
|
|
&Asn1Info,
|
|
dwFlags,
|
|
pEncodePara,
|
|
pvEncoded,
|
|
pcbEncoded
|
|
);
|
|
}
|
|
|
|
|
|
//+-------------------------------------------------------------------------
|
|
// Certificate Policies Extension Encode (ASN1 X509)
|
|
//--------------------------------------------------------------------------
|
|
BOOL WINAPI Asn1X509CertPoliciesEncodeEx(
|
|
IN DWORD dwCertEncodingType,
|
|
IN LPCSTR lpszStructType,
|
|
IN PCERT_POLICIES_INFO pInfo,
|
|
IN DWORD dwFlags,
|
|
IN OPTIONAL PCRYPT_ENCODE_PARA pEncodePara,
|
|
OUT OPTIONAL void *pvEncoded,
|
|
IN OUT DWORD *pcbEncoded
|
|
)
|
|
{
|
|
BOOL fResult;
|
|
DWORD cPolicyInfo;
|
|
|
|
CertificatePolicies Asn1Info;
|
|
memset(&Asn1Info, 0, sizeof(Asn1Info));
|
|
|
|
cPolicyInfo = pInfo->cPolicyInfo;
|
|
if (cPolicyInfo) {
|
|
PCERT_POLICY_INFO pPolicyInfo = pInfo->rgPolicyInfo;
|
|
PolicyInformation *pAsn1PolicyInfo =
|
|
(PolicyInformation *) PkiZeroAlloc(
|
|
cPolicyInfo * sizeof(PolicyInformation));
|
|
if (pAsn1PolicyInfo == NULL) goto ErrorReturn;
|
|
Asn1Info.count = cPolicyInfo;
|
|
Asn1Info.value = pAsn1PolicyInfo;
|
|
|
|
for ( ; cPolicyInfo > 0;
|
|
cPolicyInfo--, pPolicyInfo++, pAsn1PolicyInfo++) {
|
|
DWORD cQualifier = pPolicyInfo->cPolicyQualifier;
|
|
if (!Asn1X509SetEncodedObjId(pPolicyInfo->pszPolicyIdentifier,
|
|
&pAsn1PolicyInfo->policyIdentifier))
|
|
goto ErrorReturn;
|
|
if (cQualifier > 0) {
|
|
PCERT_POLICY_QUALIFIER_INFO pQualifier =
|
|
pPolicyInfo->rgPolicyQualifier;
|
|
PolicyQualifierInfo *pAsn1Qualifier =
|
|
(PolicyQualifierInfo *) PkiZeroAlloc(
|
|
cQualifier * sizeof(PolicyQualifierInfo));
|
|
if (pAsn1Qualifier == NULL) goto ErrorReturn;
|
|
pAsn1PolicyInfo->policyQualifiers.count = cQualifier;
|
|
pAsn1PolicyInfo->policyQualifiers.value = pAsn1Qualifier;
|
|
pAsn1PolicyInfo->bit_mask |= policyQualifiers_present;
|
|
|
|
for ( ; cQualifier > 0;
|
|
cQualifier--, pQualifier++, pAsn1Qualifier++) {
|
|
if (!Asn1X509SetEncodedObjId(pQualifier->pszPolicyQualifierId,
|
|
&pAsn1Qualifier->policyQualifierId))
|
|
goto ErrorReturn;
|
|
|
|
if (pQualifier->Qualifier.cbData) {
|
|
Asn1X509SetAny(&pQualifier->Qualifier,
|
|
&pAsn1Qualifier->qualifier);
|
|
pAsn1Qualifier->bit_mask |= qualifier_present;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
fResult = Asn1InfoEncodeEx(
|
|
CertificatePolicies_PDU,
|
|
&Asn1Info,
|
|
dwFlags,
|
|
pEncodePara,
|
|
pvEncoded,
|
|
pcbEncoded
|
|
);
|
|
|
|
goto CommonReturn;
|
|
|
|
ErrorReturn:
|
|
if (dwFlags & CRYPT_ENCODE_ALLOC_FLAG)
|
|
*((void **) pvEncoded) = NULL;
|
|
*pcbEncoded = 0;
|
|
fResult = FALSE;
|
|
CommonReturn:
|
|
if (Asn1Info.value) {
|
|
cPolicyInfo = Asn1Info.count;
|
|
PolicyInformation *pAsn1PolicyInfo = Asn1Info.value;
|
|
for ( ; cPolicyInfo > 0; cPolicyInfo--, pAsn1PolicyInfo++)
|
|
if (pAsn1PolicyInfo->policyQualifiers.value)
|
|
PkiFree(pAsn1PolicyInfo->policyQualifiers.value);
|
|
PkiFree(Asn1Info.value);
|
|
}
|
|
return fResult;
|
|
}
|
|
|
|
|
|
//+-------------------------------------------------------------------------
|
|
// Certificate Policies Extension Decode (ASN1 X509)
|
|
//--------------------------------------------------------------------------
|
|
BOOL WINAPI Asn1X509CertPoliciesDecodeExCallback(
|
|
IN void *pvAsn1Info,
|
|
IN DWORD dwFlags,
|
|
IN OPTIONAL PCRYPT_DECODE_PARA pDecodePara,
|
|
OUT OPTIONAL void *pvStructInfo,
|
|
IN OUT LONG *plRemainExtra
|
|
)
|
|
{
|
|
CertificatePolicies *pAsn1Info = (CertificatePolicies *) pvAsn1Info;
|
|
PCERT_POLICIES_INFO pInfo = (PCERT_POLICIES_INFO) pvStructInfo;
|
|
LONG lRemainExtra = *plRemainExtra;
|
|
BYTE *pbExtra;
|
|
DWORD cPolicyInfo;
|
|
|
|
lRemainExtra -= sizeof(CERT_POLICIES_INFO);
|
|
if (lRemainExtra < 0) {
|
|
pbExtra = NULL;
|
|
} else {
|
|
memset(pInfo, 0, sizeof(CERT_POLICIES_INFO));
|
|
pbExtra = (BYTE *) pInfo + sizeof(CERT_POLICIES_INFO);
|
|
}
|
|
|
|
cPolicyInfo = pAsn1Info->count;
|
|
if (cPolicyInfo) {
|
|
LONG lAlignExtra;
|
|
PCERT_POLICY_INFO pPolicyInfo;
|
|
PolicyInformation *pAsn1PolicyInfo;
|
|
|
|
lAlignExtra = INFO_LEN_ALIGN(cPolicyInfo * sizeof(CERT_POLICY_INFO));
|
|
lRemainExtra -= lAlignExtra;
|
|
if (lRemainExtra >= 0) {
|
|
pInfo->cPolicyInfo = cPolicyInfo;
|
|
pPolicyInfo = (PCERT_POLICY_INFO) pbExtra;
|
|
pInfo->rgPolicyInfo = pPolicyInfo;
|
|
memset(pPolicyInfo, 0, cPolicyInfo * sizeof(CERT_POLICY_INFO));
|
|
pbExtra += lAlignExtra;
|
|
} else
|
|
pPolicyInfo = NULL;
|
|
|
|
pAsn1PolicyInfo = pAsn1Info->value;
|
|
for ( ; cPolicyInfo > 0;
|
|
cPolicyInfo--, pPolicyInfo++, pAsn1PolicyInfo++) {
|
|
DWORD cQualifier;
|
|
|
|
// check to see if there is a policy identifier
|
|
if (pAsn1PolicyInfo->policyIdentifier.length != 0) {
|
|
Asn1X509GetEncodedObjId(&pAsn1PolicyInfo->policyIdentifier, dwFlags,
|
|
&pPolicyInfo->pszPolicyIdentifier, &pbExtra, &lRemainExtra);
|
|
}
|
|
else {
|
|
lAlignExtra = INFO_LEN_ALIGN(strlen("")+1);
|
|
lRemainExtra -= lAlignExtra;
|
|
if (lRemainExtra >= 0) {
|
|
pPolicyInfo->pszPolicyIdentifier = (LPSTR) pbExtra;
|
|
strcpy(pPolicyInfo->pszPolicyIdentifier, "");
|
|
pbExtra += lAlignExtra;
|
|
}
|
|
}
|
|
|
|
cQualifier = pAsn1PolicyInfo->bit_mask & policyQualifiers_present ?
|
|
pAsn1PolicyInfo->policyQualifiers.count : 0;
|
|
if (cQualifier > 0) {
|
|
PCERT_POLICY_QUALIFIER_INFO pQualifier;
|
|
PolicyQualifierInfo *pAsn1Qualifier;
|
|
|
|
lAlignExtra = INFO_LEN_ALIGN(cQualifier *
|
|
sizeof(CERT_POLICY_QUALIFIER_INFO));
|
|
lRemainExtra -= lAlignExtra;
|
|
if (lRemainExtra >= 0) {
|
|
pPolicyInfo->cPolicyQualifier = cQualifier;
|
|
pQualifier = (PCERT_POLICY_QUALIFIER_INFO) pbExtra;
|
|
pPolicyInfo->rgPolicyQualifier = pQualifier;
|
|
memset(pQualifier, 0,
|
|
cQualifier * sizeof(CERT_POLICY_QUALIFIER_INFO));
|
|
pbExtra += lAlignExtra;
|
|
} else
|
|
pQualifier = NULL;
|
|
|
|
pAsn1Qualifier = pAsn1PolicyInfo->policyQualifiers.value;
|
|
for ( ; cQualifier > 0;
|
|
cQualifier--, pQualifier++, pAsn1Qualifier++) {
|
|
Asn1X509GetEncodedObjId(&pAsn1Qualifier->policyQualifierId, dwFlags,
|
|
&pQualifier->pszPolicyQualifierId,
|
|
&pbExtra, &lRemainExtra);
|
|
if (pAsn1Qualifier->bit_mask & qualifier_present)
|
|
Asn1X509GetAny(&pAsn1Qualifier->qualifier, dwFlags,
|
|
&pQualifier->Qualifier, &pbExtra, &lRemainExtra);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
*plRemainExtra = lRemainExtra;
|
|
return TRUE;
|
|
}
|
|
|
|
BOOL WINAPI Asn1X509CertPoliciesDecodeEx(
|
|
IN DWORD dwCertEncodingType,
|
|
IN LPCSTR lpszStructType,
|
|
IN const BYTE *pbEncoded,
|
|
IN DWORD cbEncoded,
|
|
IN DWORD dwFlags,
|
|
IN OPTIONAL PCRYPT_DECODE_PARA pDecodePara,
|
|
OUT OPTIONAL void *pvStructInfo,
|
|
IN OUT DWORD *pcbStructInfo
|
|
)
|
|
{
|
|
BOOL fResult;
|
|
CertificatePolicies *pAsn1Info = NULL;
|
|
CertificatePolicies95 *pAsn1Info95 = NULL;
|
|
PolicyInformation *pPolicyInformation = NULL;
|
|
CertificatePolicies certificatePolicies;
|
|
DWORD i;
|
|
|
|
if (!Asn1InfoDecodeAndAlloc(
|
|
CertificatePolicies_PDU,
|
|
pbEncoded,
|
|
cbEncoded,
|
|
(void **) &pAsn1Info))
|
|
{
|
|
// try to decode it as the old style
|
|
if (!Asn1InfoDecodeAndAlloc(
|
|
CertificatePolicies95_PDU,
|
|
pbEncoded,
|
|
cbEncoded,
|
|
(void **) &pAsn1Info95))
|
|
goto ErrorReturn;
|
|
|
|
// that decode worked, so alloc some memory, fix up some pointers
|
|
// and role through the rest of the routine per usual
|
|
certificatePolicies.count = pAsn1Info95->count;
|
|
if (NULL == (pPolicyInformation =
|
|
(PolicyInformation *) PkiNonzeroAlloc(pAsn1Info95->count * sizeof(PolicyInformation))))
|
|
goto ErrorReturn;
|
|
|
|
certificatePolicies.value = pPolicyInformation;
|
|
|
|
for (i=0; i<pAsn1Info95->count; i++)
|
|
{
|
|
pPolicyInformation[i].bit_mask = policyQualifiers_present;
|
|
pPolicyInformation[i].policyIdentifier.length = 0;
|
|
pPolicyInformation[i].policyIdentifier.value = NULL;
|
|
pPolicyInformation[i].policyQualifiers.count = pAsn1Info95->value[i].count;
|
|
pPolicyInformation[i].policyQualifiers.value = pAsn1Info95->value[i].value;
|
|
}
|
|
|
|
pAsn1Info = &certificatePolicies;
|
|
}
|
|
|
|
fResult = PkiAsn1AllocStructInfoEx(
|
|
pAsn1Info,
|
|
dwFlags,
|
|
pDecodePara,
|
|
Asn1X509CertPoliciesDecodeExCallback,
|
|
pvStructInfo,
|
|
pcbStructInfo
|
|
);
|
|
CommonReturn:
|
|
if (pAsn1Info95)
|
|
{
|
|
if (pPolicyInformation)
|
|
PkiFree(pPolicyInformation);
|
|
Asn1InfoFree(CertificatePolicies95_PDU, pAsn1Info95);
|
|
}
|
|
else
|
|
{
|
|
Asn1InfoFree(CertificatePolicies_PDU, pAsn1Info);
|
|
}
|
|
|
|
return fResult;
|
|
|
|
ErrorReturn:
|
|
*pcbStructInfo = 0;
|
|
fResult = FALSE;
|
|
goto CommonReturn;
|
|
}
|
|
|
|
|
|
//+-------------------------------------------------------------------------
|
|
// Policy Information 95 - Qualifier 1 decode
|
|
//--------------------------------------------------------------------------
|
|
BOOL WINAPI Asn1X509CertPoliciesQualifier1DecodeExCallback(
|
|
IN void *pvAsn1Info,
|
|
IN DWORD dwFlags,
|
|
IN OPTIONAL PCRYPT_DECODE_PARA pDecodePara,
|
|
OUT OPTIONAL void *pvStructInfo,
|
|
IN OUT LONG *plRemainExtra
|
|
)
|
|
{
|
|
VerisignQualifier1 *pAsn1Info = (VerisignQualifier1 *) pvAsn1Info;
|
|
PCERT_POLICY95_QUALIFIER1 pInfo =
|
|
(PCERT_POLICY95_QUALIFIER1) pvStructInfo;
|
|
LONG lRemainExtra = *plRemainExtra;
|
|
BYTE *pbExtra;
|
|
LONG lAlignExtra;
|
|
DWORD i;
|
|
|
|
lRemainExtra -= sizeof(CERT_POLICY95_QUALIFIER1);
|
|
if (lRemainExtra < 0) {
|
|
pbExtra = NULL;
|
|
} else {
|
|
memset(pInfo, 0, sizeof(CERT_POLICY95_QUALIFIER1));
|
|
pbExtra = (BYTE *) pInfo + sizeof(CERT_POLICY95_QUALIFIER1);
|
|
}
|
|
|
|
if (
|
|
#ifndef OSS_CRYPT_ASN1
|
|
0 != (pAsn1Info->bit_mask & practicesReference_present) &&
|
|
#endif // OSS_CRYPT_ASN1
|
|
pAsn1Info->practicesReference != NULL)
|
|
{
|
|
lAlignExtra = INFO_LEN_ALIGN((strlen(pAsn1Info->practicesReference)+1) * 2);
|
|
lRemainExtra -= lAlignExtra;
|
|
if (lRemainExtra >= 0) {
|
|
pInfo->pszPracticesReference = (LPWSTR) pbExtra;
|
|
MultiByteToWideChar(CP_ACP,
|
|
0,
|
|
pAsn1Info->practicesReference,
|
|
-1,
|
|
pInfo->pszPracticesReference,
|
|
lAlignExtra / 2); // character count
|
|
pbExtra += lAlignExtra;
|
|
}
|
|
}
|
|
else if (lRemainExtra >= 0)
|
|
{
|
|
pInfo->pszPracticesReference = NULL;
|
|
}
|
|
|
|
if (pAsn1Info->bit_mask & noticeId_present)
|
|
{
|
|
Asn1X509GetEncodedObjId(&pAsn1Info->noticeId, dwFlags,
|
|
&pInfo->pszNoticeIdentifier,
|
|
&pbExtra, &lRemainExtra);
|
|
}
|
|
else if (lRemainExtra >= 0)
|
|
{
|
|
pInfo->pszNoticeIdentifier = NULL;
|
|
}
|
|
|
|
if (pAsn1Info->bit_mask & nsiNoticeId_present)
|
|
{
|
|
Asn1X509GetEncodedObjId(&pAsn1Info->nsiNoticeId, dwFlags,
|
|
&pInfo->pszNSINoticeIdentifier,
|
|
&pbExtra, &lRemainExtra);
|
|
}
|
|
else if (lRemainExtra >= 0)
|
|
{
|
|
pInfo->pszNSINoticeIdentifier = NULL;
|
|
}
|
|
|
|
if (pAsn1Info->bit_mask & cpsURLs_present)
|
|
{
|
|
lAlignExtra = INFO_LEN_ALIGN(pAsn1Info->cpsURLs.count * sizeof(CPS_URLS));
|
|
lRemainExtra -= lAlignExtra;
|
|
if (lRemainExtra >= 0) {
|
|
pInfo->rgCPSURLs = (CPS_URLS *) pbExtra;
|
|
memset(pInfo->rgCPSURLs, 0, lAlignExtra);
|
|
pInfo->cCPSURLs = pAsn1Info->cpsURLs.count;
|
|
pbExtra += lAlignExtra;
|
|
}
|
|
|
|
for (i=0; i<pAsn1Info->cpsURLs.count; i++)
|
|
{
|
|
lAlignExtra = INFO_LEN_ALIGN((strlen(pAsn1Info->cpsURLs.value[i].url)+1) * 2);
|
|
lRemainExtra -= lAlignExtra;
|
|
if (lRemainExtra >= 0)
|
|
{
|
|
pInfo->rgCPSURLs[i].pszURL = (LPWSTR) pbExtra;
|
|
MultiByteToWideChar(CP_ACP,
|
|
0,
|
|
pAsn1Info->cpsURLs.value[i].url,
|
|
-1,
|
|
pInfo->rgCPSURLs[i].pszURL,
|
|
lAlignExtra / 2); // character count
|
|
pbExtra += lAlignExtra;
|
|
}
|
|
|
|
if (pAsn1Info->cpsURLs.value[i].bit_mask & digestAlgorithmId_present)
|
|
{
|
|
lAlignExtra = INFO_LEN_ALIGN(sizeof(CRYPT_ALGORITHM_IDENTIFIER));
|
|
lRemainExtra -= lAlignExtra;
|
|
if (lRemainExtra >= 0)
|
|
{
|
|
pInfo->rgCPSURLs[i].pAlgorithm = (CRYPT_ALGORITHM_IDENTIFIER *) pbExtra;
|
|
memset(pInfo->rgCPSURLs[i].pAlgorithm, 0, lAlignExtra);
|
|
pbExtra += lAlignExtra;
|
|
}
|
|
|
|
Asn1X509GetAlgorithm(
|
|
&(pAsn1Info->cpsURLs.value[i].digestAlgorithmId),
|
|
dwFlags,
|
|
pInfo->rgCPSURLs[i].pAlgorithm,
|
|
&pbExtra,
|
|
&lRemainExtra);
|
|
}
|
|
else if (lRemainExtra >= 0)
|
|
{
|
|
pInfo->rgCPSURLs[i].pAlgorithm = NULL;
|
|
}
|
|
|
|
if (pAsn1Info->cpsURLs.value[i].bit_mask & digest_present)
|
|
{
|
|
lAlignExtra = INFO_LEN_ALIGN(sizeof(CRYPT_DATA_BLOB));
|
|
lRemainExtra -= lAlignExtra;
|
|
if (lRemainExtra >= 0)
|
|
{
|
|
pInfo->rgCPSURLs[i].pDigest = (CRYPT_DATA_BLOB *) pbExtra;
|
|
memset(pInfo->rgCPSURLs[i].pDigest, 0, lAlignExtra);
|
|
pbExtra += lAlignExtra;
|
|
}
|
|
|
|
Asn1X509GetOctetString(
|
|
&(pAsn1Info->cpsURLs.value[i].digest),
|
|
dwFlags,
|
|
pInfo->rgCPSURLs[i].pDigest,
|
|
&pbExtra,
|
|
&lRemainExtra);
|
|
}
|
|
else if (lRemainExtra >= 0)
|
|
{
|
|
pInfo->rgCPSURLs[i].pDigest = NULL;
|
|
}
|
|
}
|
|
}
|
|
else if (lRemainExtra >= 0)
|
|
{
|
|
pInfo->rgCPSURLs = NULL;
|
|
}
|
|
|
|
*plRemainExtra = lRemainExtra;
|
|
return TRUE;
|
|
}
|
|
|
|
BOOL WINAPI Asn1X509CertPoliciesQualifier1DecodeEx(
|
|
IN DWORD dwCertEncodingType,
|
|
IN LPCSTR lpszStructType,
|
|
IN const BYTE *pbEncoded,
|
|
IN DWORD cbEncoded,
|
|
IN DWORD dwFlags,
|
|
IN OPTIONAL PCRYPT_DECODE_PARA pDecodePara,
|
|
OUT OPTIONAL void *pvStructInfo,
|
|
IN OUT DWORD *pcbStructInfo
|
|
)
|
|
{
|
|
return Asn1InfoDecodeAndAllocEx(
|
|
VerisignQualifier1_PDU,
|
|
pbEncoded,
|
|
cbEncoded,
|
|
dwFlags,
|
|
pDecodePara,
|
|
Asn1X509CertPoliciesQualifier1DecodeExCallback,
|
|
pvStructInfo,
|
|
pcbStructInfo
|
|
);
|
|
}
|
|
|
|
|
|
//+-------------------------------------------------------------------------
|
|
// Authority Information Access Extension Encode (ASN1 X509)
|
|
//--------------------------------------------------------------------------
|
|
BOOL WINAPI Asn1X509AuthorityInfoAccessEncodeEx(
|
|
IN DWORD dwCertEncodingType,
|
|
IN LPCSTR lpszStructType,
|
|
IN PCERT_AUTHORITY_INFO_ACCESS pInfo,
|
|
IN DWORD dwFlags,
|
|
IN OPTIONAL PCRYPT_ENCODE_PARA pEncodePara,
|
|
OUT OPTIONAL void *pvEncoded,
|
|
IN OUT DWORD *pcbEncoded
|
|
)
|
|
{
|
|
BOOL fResult;
|
|
AuthorityInfoAccess Asn1Info;
|
|
DWORD cAccDescr;
|
|
AccessDescription *pAsn1AccDescr;
|
|
DWORD dwErrLocation;
|
|
|
|
if (dwFlags & CRYPT_ENCODE_ALLOC_FLAG)
|
|
*((void **) pvEncoded) = NULL;
|
|
|
|
memset(&Asn1Info, 0, sizeof(Asn1Info));
|
|
|
|
cAccDescr = pInfo->cAccDescr;
|
|
if (cAccDescr > 0) {
|
|
pAsn1AccDescr =
|
|
(AccessDescription *) PkiZeroAlloc(cAccDescr *
|
|
sizeof(AccessDescription));
|
|
if (pAsn1AccDescr == NULL)
|
|
goto ErrorReturn;
|
|
Asn1Info.count = cAccDescr;
|
|
Asn1Info.value = pAsn1AccDescr;
|
|
|
|
if (!Asn1X509SetAccessDescriptions(
|
|
cAccDescr,
|
|
pInfo->rgAccDescr,
|
|
pAsn1AccDescr,
|
|
&dwErrLocation))
|
|
goto AccessDescriptionsError;
|
|
|
|
} else
|
|
pAsn1AccDescr = NULL;
|
|
|
|
fResult = Asn1InfoEncodeEx(
|
|
AuthorityInfoAccess_PDU,
|
|
&Asn1Info,
|
|
dwFlags,
|
|
pEncodePara,
|
|
pvEncoded,
|
|
pcbEncoded
|
|
);
|
|
goto CommonReturn;
|
|
|
|
AccessDescriptionsError:
|
|
*pcbEncoded = dwErrLocation;
|
|
fResult = FALSE;
|
|
goto CommonReturn;
|
|
|
|
ErrorReturn:
|
|
*pcbEncoded = 0;
|
|
fResult = FALSE;
|
|
CommonReturn:
|
|
if (pAsn1AccDescr) {
|
|
Asn1X509FreeAccessDescriptions(cAccDescr, pAsn1AccDescr);
|
|
PkiFree(pAsn1AccDescr);
|
|
}
|
|
return fResult;
|
|
}
|
|
|
|
//+-------------------------------------------------------------------------
|
|
// Authority Information Access Extension Decode (ASN1 X509)
|
|
//--------------------------------------------------------------------------
|
|
BOOL WINAPI Asn1X509AuthorityInfoAccessDecodeExCallback(
|
|
IN void *pvAsn1Info,
|
|
IN DWORD dwFlags,
|
|
IN OPTIONAL PCRYPT_DECODE_PARA pDecodePara,
|
|
OUT OPTIONAL void *pvStructInfo,
|
|
IN OUT LONG *plRemainExtra
|
|
)
|
|
{
|
|
BOOL fResult;
|
|
AuthorityInfoAccess *pAsn1 = (AuthorityInfoAccess *) pvAsn1Info;
|
|
PCERT_AUTHORITY_INFO_ACCESS pInfo =
|
|
(PCERT_AUTHORITY_INFO_ACCESS) pvStructInfo;
|
|
LONG lRemainExtra = *plRemainExtra;
|
|
BYTE *pbExtra;
|
|
LONG lAlignExtra;
|
|
DWORD cAccDescr;
|
|
PCERT_ACCESS_DESCRIPTION pAccDescr;
|
|
|
|
cAccDescr = pAsn1->count;
|
|
lAlignExtra = INFO_LEN_ALIGN(cAccDescr * sizeof(CERT_ACCESS_DESCRIPTION));
|
|
|
|
lRemainExtra -= sizeof(CERT_AUTHORITY_INFO_ACCESS) + lAlignExtra;
|
|
if (lRemainExtra < 0) {
|
|
pbExtra = NULL;
|
|
pAccDescr = NULL;
|
|
} else {
|
|
pbExtra = (BYTE *) pInfo + sizeof(CERT_AUTHORITY_INFO_ACCESS);
|
|
pAccDescr = (PCERT_ACCESS_DESCRIPTION) pbExtra;
|
|
pInfo->cAccDescr = cAccDescr;
|
|
pInfo->rgAccDescr = pAccDescr;
|
|
pbExtra += lAlignExtra;
|
|
}
|
|
|
|
if (!Asn1X509GetAccessDescriptions(
|
|
cAccDescr,
|
|
pAsn1->value,
|
|
dwFlags,
|
|
pAccDescr,
|
|
&pbExtra,
|
|
&lRemainExtra
|
|
)) goto ErrorReturn;
|
|
|
|
fResult = TRUE;
|
|
CommonReturn:
|
|
*plRemainExtra = lRemainExtra;
|
|
return fResult;
|
|
|
|
ErrorReturn:
|
|
fResult = FALSE;
|
|
goto CommonReturn;
|
|
}
|
|
|
|
|
|
BOOL WINAPI Asn1X509AuthorityInfoAccessDecodeEx(
|
|
IN DWORD dwCertEncodingType,
|
|
IN LPCSTR lpszStructType,
|
|
IN const BYTE *pbEncoded,
|
|
IN DWORD cbEncoded,
|
|
IN DWORD dwFlags,
|
|
IN OPTIONAL PCRYPT_DECODE_PARA pDecodePara,
|
|
OUT OPTIONAL void *pvStructInfo,
|
|
IN OUT DWORD *pcbStructInfo
|
|
)
|
|
{
|
|
return Asn1InfoDecodeAndAllocEx(
|
|
AuthorityInfoAccess_PDU,
|
|
pbEncoded,
|
|
cbEncoded,
|
|
dwFlags,
|
|
pDecodePara,
|
|
Asn1X509AuthorityInfoAccessDecodeExCallback,
|
|
pvStructInfo,
|
|
pcbStructInfo
|
|
);
|
|
}
|
|
|
|
//+-------------------------------------------------------------------------
|
|
// CRL Distribution Points Encode (ASN1 X509)
|
|
//--------------------------------------------------------------------------
|
|
BOOL WINAPI Asn1X509CrlDistPointsEncodeEx(
|
|
IN DWORD dwCertEncodingType,
|
|
IN LPCSTR lpszStructType,
|
|
IN PCRL_DIST_POINTS_INFO pInfo,
|
|
IN DWORD dwFlags,
|
|
IN OPTIONAL PCRYPT_ENCODE_PARA pEncodePara,
|
|
OUT OPTIONAL void *pvEncoded,
|
|
IN OUT DWORD *pcbEncoded
|
|
)
|
|
{
|
|
BOOL fResult;
|
|
CRLDistributionPoints Asn1Info;
|
|
DistributionPoint *pAsn1DistPoint;
|
|
PCRL_DIST_POINT pDistPoint;
|
|
DWORD cDistPoint;
|
|
DWORD i;
|
|
DWORD dwErrLocation;
|
|
|
|
if (dwFlags & CRYPT_ENCODE_ALLOC_FLAG)
|
|
*((void **) pvEncoded) = NULL;
|
|
|
|
memset(&Asn1Info, 0, sizeof(Asn1Info));
|
|
if (0 == (cDistPoint = pInfo->cDistPoint))
|
|
goto InvalidArg;
|
|
|
|
if (NULL == (pAsn1DistPoint = (DistributionPoint *) PkiZeroAlloc(
|
|
cDistPoint * sizeof(DistributionPoint))))
|
|
goto ErrorReturn;
|
|
Asn1Info.count = cDistPoint;
|
|
Asn1Info.value = pAsn1DistPoint;
|
|
|
|
pDistPoint = pInfo->rgDistPoint;
|
|
for (i = 0; i < cDistPoint; i++, pDistPoint++, pAsn1DistPoint++) {
|
|
PCRL_DIST_POINT_NAME pDistPointName =
|
|
&pDistPoint->DistPointName;
|
|
if (CRL_DIST_POINT_NO_NAME !=
|
|
pDistPointName->dwDistPointNameChoice) {
|
|
DistributionPointName *pAsn1DistPointName =
|
|
&pAsn1DistPoint->distributionPoint;
|
|
|
|
pAsn1DistPoint->bit_mask |= distributionPoint_present;
|
|
pAsn1DistPointName->choice = (unsigned short)
|
|
pDistPointName->dwDistPointNameChoice;
|
|
|
|
assert(fullName_chosen == CRL_DIST_POINT_FULL_NAME);
|
|
assert(nameRelativeToCRLIssuer_chosen ==
|
|
CRL_DIST_POINT_ISSUER_RDN_NAME);
|
|
|
|
switch (pDistPointName->dwDistPointNameChoice) {
|
|
case CRL_DIST_POINT_FULL_NAME:
|
|
if (!Asn1X509SetAltNames(
|
|
&pDistPointName->FullName,
|
|
&pAsn1DistPointName->u.fullName, i, &dwErrLocation))
|
|
goto AltNamesError;
|
|
break;
|
|
case CRL_DIST_POINT_ISSUER_RDN_NAME:
|
|
default:
|
|
goto InvalidArg;
|
|
}
|
|
}
|
|
|
|
if (pDistPoint->ReasonFlags.cbData) {
|
|
pAsn1DistPoint->bit_mask |= reasons_present;
|
|
Asn1X509SetBitWithoutTrailingZeroes(&pDistPoint->ReasonFlags,
|
|
&pAsn1DistPoint->reasons);
|
|
}
|
|
|
|
if (pDistPoint->CRLIssuer.cAltEntry) {
|
|
pAsn1DistPoint->bit_mask |= cRLIssuer_present;
|
|
if (!Asn1X509SetAltNames(
|
|
&pDistPoint->CRLIssuer,
|
|
&pAsn1DistPoint->cRLIssuer,
|
|
(CRL_DIST_POINT_ERR_CRL_ISSUER_BIT >> 24) | i,
|
|
&dwErrLocation))
|
|
goto AltNamesError;
|
|
}
|
|
}
|
|
|
|
fResult = Asn1InfoEncodeEx(
|
|
CRLDistributionPoints_PDU,
|
|
&Asn1Info,
|
|
dwFlags,
|
|
pEncodePara,
|
|
pvEncoded,
|
|
pcbEncoded
|
|
);
|
|
goto CommonReturn;
|
|
|
|
|
|
AltNamesError:
|
|
*pcbEncoded = dwErrLocation;
|
|
fResult = FALSE;
|
|
goto CommonReturn;
|
|
|
|
InvalidArg:
|
|
SetLastError((DWORD) E_INVALIDARG);
|
|
ErrorReturn:
|
|
*pcbEncoded = 0;
|
|
fResult = FALSE;
|
|
CommonReturn:
|
|
pAsn1DistPoint = Asn1Info.value;
|
|
if (pAsn1DistPoint) {
|
|
cDistPoint = Asn1Info.count;
|
|
pDistPoint = pInfo->rgDistPoint;
|
|
for ( ; cDistPoint > 0; cDistPoint--, pDistPoint++, pAsn1DistPoint++) {
|
|
DistributionPointName *pAsn1DistPointName =
|
|
&pAsn1DistPoint->distributionPoint;
|
|
|
|
switch (pAsn1DistPointName->choice) {
|
|
case CRL_DIST_POINT_FULL_NAME:
|
|
Asn1X509FreeAltNames(&pAsn1DistPointName->u.fullName);
|
|
break;
|
|
case CRL_DIST_POINT_ISSUER_RDN_NAME:
|
|
default:
|
|
break;
|
|
}
|
|
|
|
Asn1X509FreeAltNames(&pAsn1DistPoint->cRLIssuer);
|
|
}
|
|
PkiFree(Asn1Info.value);
|
|
}
|
|
return fResult;
|
|
}
|
|
|
|
//+-------------------------------------------------------------------------
|
|
// CRL Distribution Points Decode (ASN1 X509)
|
|
//--------------------------------------------------------------------------
|
|
BOOL WINAPI Asn1X509CrlDistPointsDecodeExCallback(
|
|
IN void *pvAsn1Info,
|
|
IN DWORD dwFlags,
|
|
IN OPTIONAL PCRYPT_DECODE_PARA pDecodePara,
|
|
OUT OPTIONAL void *pvStructInfo,
|
|
IN OUT LONG *plRemainExtra
|
|
)
|
|
{
|
|
BOOL fResult;
|
|
CRLDistributionPoints *pAsn1 = (CRLDistributionPoints *) pvAsn1Info;
|
|
PCRL_DIST_POINTS_INFO pInfo = (PCRL_DIST_POINTS_INFO) pvStructInfo;
|
|
LONG lRemainExtra = *plRemainExtra;
|
|
BYTE *pbExtra;
|
|
LONG lAlignExtra;
|
|
|
|
lRemainExtra -= sizeof(CRL_DIST_POINTS_INFO);
|
|
if (lRemainExtra < 0) {
|
|
pbExtra = NULL;
|
|
} else {
|
|
memset(pInfo, 0, sizeof(CRL_DIST_POINTS_INFO));
|
|
pbExtra = (BYTE *) pInfo + sizeof(CRL_DIST_POINTS_INFO);
|
|
}
|
|
|
|
if (pAsn1->count) {
|
|
DWORD cDistPoint = pAsn1->count;
|
|
DistributionPoint *pAsn1DistPoint = pAsn1->value;
|
|
PCRL_DIST_POINT pDistPoint;
|
|
|
|
lAlignExtra = INFO_LEN_ALIGN(cDistPoint * sizeof(CRL_DIST_POINT));
|
|
lRemainExtra -= lAlignExtra;
|
|
if (lRemainExtra >= 0) {
|
|
pDistPoint = (PCRL_DIST_POINT) pbExtra;
|
|
memset(pDistPoint, 0, cDistPoint * sizeof(CRL_DIST_POINT));
|
|
pInfo->cDistPoint = cDistPoint;
|
|
pInfo->rgDistPoint = pDistPoint;
|
|
pbExtra += lAlignExtra;
|
|
} else
|
|
pDistPoint = NULL;
|
|
|
|
for ( ; cDistPoint > 0; cDistPoint--, pAsn1DistPoint++, pDistPoint++) {
|
|
if (pAsn1DistPoint->bit_mask & distributionPoint_present) {
|
|
DistributionPointName *pAsn1DistPointName =
|
|
&pAsn1DistPoint->distributionPoint;
|
|
DWORD dwDistPointNameChoice = pAsn1DistPointName->choice;
|
|
PCRL_DIST_POINT_NAME pDistPointName;
|
|
|
|
if (lRemainExtra >= 0) {
|
|
pDistPointName = &pDistPoint->DistPointName;
|
|
pDistPointName->dwDistPointNameChoice =
|
|
dwDistPointNameChoice;
|
|
} else
|
|
pDistPointName = NULL;
|
|
|
|
assert(fullName_chosen == CRL_DIST_POINT_FULL_NAME);
|
|
assert(nameRelativeToCRLIssuer_chosen ==
|
|
CRL_DIST_POINT_ISSUER_RDN_NAME);
|
|
|
|
switch (dwDistPointNameChoice) {
|
|
case CRL_DIST_POINT_FULL_NAME:
|
|
if (!Asn1X509GetAltNames(&pAsn1DistPointName->u.fullName,
|
|
dwFlags, &pDistPointName->FullName,
|
|
&pbExtra, &lRemainExtra))
|
|
goto ErrorReturn;
|
|
break;
|
|
case CRL_DIST_POINT_ISSUER_RDN_NAME:
|
|
break;
|
|
default:
|
|
SetLastError((DWORD) CRYPT_E_BAD_ENCODE);
|
|
goto ErrorReturn;
|
|
}
|
|
}
|
|
|
|
if (pAsn1DistPoint->bit_mask & reasons_present)
|
|
Asn1X509GetBit(&pAsn1DistPoint->reasons, dwFlags,
|
|
&pDistPoint->ReasonFlags, &pbExtra, &lRemainExtra);
|
|
|
|
if (pAsn1DistPoint->bit_mask & cRLIssuer_present) {
|
|
if (!Asn1X509GetAltNames(&pAsn1DistPoint->cRLIssuer, dwFlags,
|
|
&pDistPoint->CRLIssuer, &pbExtra, &lRemainExtra))
|
|
goto ErrorReturn;
|
|
}
|
|
}
|
|
}
|
|
|
|
fResult = TRUE;
|
|
CommonReturn:
|
|
*plRemainExtra = lRemainExtra;
|
|
return fResult;
|
|
|
|
ErrorReturn:
|
|
fResult = FALSE;
|
|
goto CommonReturn;
|
|
}
|
|
|
|
BOOL WINAPI Asn1X509CrlDistPointsDecodeEx(
|
|
IN DWORD dwCertEncodingType,
|
|
IN LPCSTR lpszStructType,
|
|
IN const BYTE *pbEncoded,
|
|
IN DWORD cbEncoded,
|
|
IN DWORD dwFlags,
|
|
IN OPTIONAL PCRYPT_DECODE_PARA pDecodePara,
|
|
OUT OPTIONAL void *pvStructInfo,
|
|
IN OUT DWORD *pcbStructInfo
|
|
)
|
|
{
|
|
return Asn1InfoDecodeAndAllocEx(
|
|
CRLDistributionPoints_PDU,
|
|
pbEncoded,
|
|
cbEncoded,
|
|
dwFlags,
|
|
pDecodePara,
|
|
Asn1X509CrlDistPointsDecodeExCallback,
|
|
pvStructInfo,
|
|
pcbStructInfo
|
|
);
|
|
}
|
|
|
|
//+-------------------------------------------------------------------------
|
|
// Integer Extension Encode (ASN1 X509)
|
|
//--------------------------------------------------------------------------
|
|
BOOL WINAPI Asn1X509IntegerEncodeEx(
|
|
IN DWORD dwCertEncodingType,
|
|
IN LPCSTR lpszStructType,
|
|
IN int *pInfo,
|
|
IN DWORD dwFlags,
|
|
IN OPTIONAL PCRYPT_ENCODE_PARA pEncodePara,
|
|
OUT OPTIONAL void *pvEncoded,
|
|
IN OUT DWORD *pcbEncoded
|
|
)
|
|
{
|
|
int Asn1Info = *pInfo;
|
|
|
|
return Asn1InfoEncodeEx(
|
|
IntegerType_PDU,
|
|
&Asn1Info,
|
|
dwFlags,
|
|
pEncodePara,
|
|
pvEncoded,
|
|
pcbEncoded
|
|
);
|
|
}
|
|
|
|
//+-------------------------------------------------------------------------
|
|
// Integer Extension Decode (ASN1 X509)
|
|
//--------------------------------------------------------------------------
|
|
BOOL WINAPI Asn1X509IntegerDecodeExCallback(
|
|
IN void *pvAsn1Info,
|
|
IN DWORD dwFlags,
|
|
IN OPTIONAL PCRYPT_DECODE_PARA pDecodePara,
|
|
OUT OPTIONAL void *pvStructInfo,
|
|
IN OUT LONG *plRemainExtra
|
|
)
|
|
{
|
|
int *pAsn1Info = (int *) pvAsn1Info;
|
|
int *pInfo = (int *) pvStructInfo;
|
|
|
|
*plRemainExtra -= sizeof(int);
|
|
if (*plRemainExtra >= 0)
|
|
*pInfo = *pAsn1Info;
|
|
return TRUE;
|
|
}
|
|
|
|
BOOL WINAPI Asn1X509IntegerDecodeEx(
|
|
IN DWORD dwCertEncodingType,
|
|
IN LPCSTR lpszStructType,
|
|
IN const BYTE *pbEncoded,
|
|
IN DWORD cbEncoded,
|
|
IN DWORD dwFlags,
|
|
IN OPTIONAL PCRYPT_DECODE_PARA pDecodePara,
|
|
OUT OPTIONAL void *pvStructInfo,
|
|
IN OUT DWORD *pcbStructInfo
|
|
)
|
|
{
|
|
return Asn1InfoDecodeAndAllocEx(
|
|
IntegerType_PDU,
|
|
pbEncoded,
|
|
cbEncoded,
|
|
dwFlags,
|
|
pDecodePara,
|
|
Asn1X509IntegerDecodeExCallback,
|
|
pvStructInfo,
|
|
pcbStructInfo
|
|
);
|
|
}
|
|
|
|
//+-------------------------------------------------------------------------
|
|
// MultiByte Integer Extension Encode (ASN1 X509)
|
|
//--------------------------------------------------------------------------
|
|
BOOL WINAPI Asn1X509MultiByteIntegerEncodeEx(
|
|
IN DWORD dwCertEncodingType,
|
|
IN LPCSTR lpszStructType,
|
|
IN PCRYPT_INTEGER_BLOB pInfo,
|
|
IN DWORD dwFlags,
|
|
IN OPTIONAL PCRYPT_ENCODE_PARA pEncodePara,
|
|
OUT OPTIONAL void *pvEncoded,
|
|
IN OUT DWORD *pcbEncoded
|
|
)
|
|
{
|
|
BOOL fResult;
|
|
HUGEINTEGER Asn1Info;
|
|
|
|
|
|
if (!Asn1X509SetHugeInteger(pInfo, &Asn1Info)) {
|
|
if (dwFlags & CRYPT_ENCODE_ALLOC_FLAG)
|
|
*((void **) pvEncoded) = NULL;
|
|
*pcbEncoded = 0;
|
|
return FALSE;
|
|
}
|
|
fResult = Asn1InfoEncodeEx(
|
|
HugeIntegerType_PDU,
|
|
&Asn1Info,
|
|
dwFlags,
|
|
pEncodePara,
|
|
pvEncoded,
|
|
pcbEncoded
|
|
);
|
|
Asn1X509FreeHugeInteger(&Asn1Info);
|
|
return fResult;
|
|
}
|
|
|
|
//+-------------------------------------------------------------------------
|
|
// MultiByte Integer Extension Decode (ASN1 X509)
|
|
//--------------------------------------------------------------------------
|
|
BOOL WINAPI Asn1X509MultiByteIntegerDecodeExCallback(
|
|
IN void *pvAsn1Info,
|
|
IN DWORD dwFlags,
|
|
IN OPTIONAL PCRYPT_DECODE_PARA pDecodePara,
|
|
OUT OPTIONAL void *pvStructInfo,
|
|
IN OUT LONG *plRemainExtra
|
|
)
|
|
{
|
|
HUGEINTEGER *pAsn1Info = (HUGEINTEGER *) pvAsn1Info;
|
|
PCRYPT_INTEGER_BLOB pInfo = (PCRYPT_INTEGER_BLOB) pvStructInfo;
|
|
LONG lRemainExtra = *plRemainExtra;
|
|
BYTE *pbExtra;
|
|
|
|
lRemainExtra -= sizeof(CRYPT_INTEGER_BLOB);
|
|
if (lRemainExtra < 0) {
|
|
pbExtra = NULL;
|
|
} else
|
|
pbExtra = (BYTE *) pInfo + sizeof(CRYPT_INTEGER_BLOB);
|
|
|
|
Asn1X509GetHugeInteger(pAsn1Info, dwFlags, pInfo, &pbExtra, &lRemainExtra);
|
|
|
|
*plRemainExtra = lRemainExtra;
|
|
return TRUE;
|
|
}
|
|
|
|
BOOL WINAPI Asn1X509MultiByteIntegerDecodeEx(
|
|
IN DWORD dwCertEncodingType,
|
|
IN LPCSTR lpszStructType,
|
|
IN const BYTE *pbEncoded,
|
|
IN DWORD cbEncoded,
|
|
IN DWORD dwFlags,
|
|
IN OPTIONAL PCRYPT_DECODE_PARA pDecodePara,
|
|
OUT OPTIONAL void *pvStructInfo,
|
|
IN OUT DWORD *pcbStructInfo
|
|
)
|
|
{
|
|
return Asn1InfoDecodeAndAllocEx(
|
|
HugeIntegerType_PDU,
|
|
pbEncoded,
|
|
cbEncoded,
|
|
dwFlags,
|
|
pDecodePara,
|
|
Asn1X509MultiByteIntegerDecodeExCallback,
|
|
pvStructInfo,
|
|
pcbStructInfo
|
|
);
|
|
}
|
|
|
|
//+-------------------------------------------------------------------------
|
|
// MultiByte UINT Extension Encode (ASN1 X509)
|
|
//--------------------------------------------------------------------------
|
|
BOOL WINAPI Asn1X509MultiByteUINTEncodeEx(
|
|
IN DWORD dwCertEncodingType,
|
|
IN LPCSTR lpszStructType,
|
|
IN PCRYPT_UINT_BLOB pInfo,
|
|
IN DWORD dwFlags,
|
|
IN OPTIONAL PCRYPT_ENCODE_PARA pEncodePara,
|
|
OUT OPTIONAL void *pvEncoded,
|
|
IN OUT DWORD *pcbEncoded
|
|
)
|
|
{
|
|
BOOL fResult;
|
|
HUGEINTEGER Asn1Info;
|
|
|
|
if (!Asn1X509SetHugeUINT(pInfo, &Asn1Info)) {
|
|
if (dwFlags & CRYPT_ENCODE_ALLOC_FLAG)
|
|
*((void **) pvEncoded) = NULL;
|
|
*pcbEncoded = 0;
|
|
return FALSE;
|
|
}
|
|
fResult = Asn1InfoEncodeEx(
|
|
HugeIntegerType_PDU,
|
|
&Asn1Info,
|
|
dwFlags,
|
|
pEncodePara,
|
|
pvEncoded,
|
|
pcbEncoded
|
|
);
|
|
Asn1X509FreeHugeUINT(&Asn1Info);
|
|
return fResult;
|
|
}
|
|
|
|
//+-------------------------------------------------------------------------
|
|
// MultiByte UINT Extension Decode (ASN1 X509)
|
|
//--------------------------------------------------------------------------
|
|
BOOL WINAPI Asn1X509MultiByteUINTDecodeExCallback(
|
|
IN void *pvAsn1Info,
|
|
IN DWORD dwFlags,
|
|
IN OPTIONAL PCRYPT_DECODE_PARA pDecodePara,
|
|
OUT OPTIONAL void *pvStructInfo,
|
|
IN OUT LONG *plRemainExtra
|
|
)
|
|
{
|
|
HUGEINTEGER *pAsn1Info = (HUGEINTEGER *) pvAsn1Info;
|
|
PCRYPT_UINT_BLOB pInfo = (PCRYPT_UINT_BLOB) pvStructInfo;
|
|
LONG lRemainExtra = *plRemainExtra;
|
|
BYTE *pbExtra;
|
|
|
|
lRemainExtra -= sizeof(CRYPT_UINT_BLOB);
|
|
if (lRemainExtra < 0) {
|
|
pbExtra = NULL;
|
|
} else
|
|
pbExtra = (BYTE *) pInfo + sizeof(CRYPT_UINT_BLOB);
|
|
|
|
Asn1X509GetHugeUINT(pAsn1Info, dwFlags, pInfo, &pbExtra, &lRemainExtra);
|
|
|
|
*plRemainExtra = lRemainExtra;
|
|
return TRUE;
|
|
}
|
|
|
|
BOOL WINAPI Asn1X509MultiByteUINTDecodeEx(
|
|
IN DWORD dwCertEncodingType,
|
|
IN LPCSTR lpszStructType,
|
|
IN const BYTE *pbEncoded,
|
|
IN DWORD cbEncoded,
|
|
IN DWORD dwFlags,
|
|
IN OPTIONAL PCRYPT_DECODE_PARA pDecodePara,
|
|
OUT OPTIONAL void *pvStructInfo,
|
|
IN OUT DWORD *pcbStructInfo
|
|
)
|
|
{
|
|
return Asn1InfoDecodeAndAllocEx(
|
|
HugeIntegerType_PDU,
|
|
pbEncoded,
|
|
cbEncoded,
|
|
dwFlags,
|
|
pDecodePara,
|
|
Asn1X509MultiByteUINTDecodeExCallback,
|
|
pvStructInfo,
|
|
pcbStructInfo
|
|
);
|
|
}
|
|
|
|
//+-------------------------------------------------------------------------
|
|
// DSS Parameters Encode (ASN1 X509)
|
|
//--------------------------------------------------------------------------
|
|
BOOL WINAPI Asn1X509DSSParametersEncodeEx(
|
|
IN DWORD dwCertEncodingType,
|
|
IN LPCSTR lpszStructType,
|
|
IN PCERT_DSS_PARAMETERS pInfo,
|
|
IN DWORD dwFlags,
|
|
IN OPTIONAL PCRYPT_ENCODE_PARA pEncodePara,
|
|
OUT OPTIONAL void *pvEncoded,
|
|
IN OUT DWORD *pcbEncoded
|
|
)
|
|
{
|
|
BOOL fResult;
|
|
DSSParameters Asn1Info;
|
|
|
|
memset(&Asn1Info, 0, sizeof(Asn1Info));
|
|
if (!Asn1X509SetHugeUINT(&pInfo->p, &Asn1Info.p))
|
|
goto ErrorReturn;
|
|
if (!Asn1X509SetHugeUINT(&pInfo->q, &Asn1Info.q))
|
|
goto ErrorReturn;
|
|
if (!Asn1X509SetHugeUINT(&pInfo->g, &Asn1Info.g))
|
|
goto ErrorReturn;
|
|
|
|
fResult = Asn1InfoEncodeEx(
|
|
DSSParameters_PDU,
|
|
&Asn1Info,
|
|
dwFlags,
|
|
pEncodePara,
|
|
pvEncoded,
|
|
pcbEncoded
|
|
);
|
|
|
|
goto CommonReturn;
|
|
|
|
ErrorReturn:
|
|
if (dwFlags & CRYPT_ENCODE_ALLOC_FLAG)
|
|
*((void **) pvEncoded) = NULL;
|
|
*pcbEncoded = 0;
|
|
fResult = FALSE;
|
|
CommonReturn:
|
|
Asn1X509FreeHugeUINT(&Asn1Info.p);
|
|
Asn1X509FreeHugeUINT(&Asn1Info.q);
|
|
Asn1X509FreeHugeUINT(&Asn1Info.g);
|
|
return fResult;
|
|
}
|
|
|
|
//+-------------------------------------------------------------------------
|
|
// DSS Parameters Decode (ASN1 X509)
|
|
//--------------------------------------------------------------------------
|
|
BOOL WINAPI Asn1X509DSSParametersDecodeExCallback(
|
|
IN void *pvAsn1Info,
|
|
IN DWORD dwFlags,
|
|
IN OPTIONAL PCRYPT_DECODE_PARA pDecodePara,
|
|
OUT OPTIONAL void *pvStructInfo,
|
|
IN OUT LONG *plRemainExtra
|
|
)
|
|
{
|
|
DSSParameters *pAsn1Info = (DSSParameters *) pvAsn1Info;
|
|
PCERT_DSS_PARAMETERS pInfo = (PCERT_DSS_PARAMETERS) pvStructInfo;
|
|
LONG lRemainExtra = *plRemainExtra;
|
|
BYTE *pbExtra;
|
|
|
|
lRemainExtra -= sizeof(CERT_DSS_PARAMETERS);
|
|
if (lRemainExtra < 0) {
|
|
pbExtra = NULL;
|
|
} else
|
|
pbExtra = (BYTE *) pInfo + sizeof(CERT_DSS_PARAMETERS);
|
|
|
|
Asn1X509GetHugeUINT(&pAsn1Info->p, dwFlags,
|
|
&pInfo->p, &pbExtra, &lRemainExtra);
|
|
Asn1X509GetHugeUINT(&pAsn1Info->q, dwFlags,
|
|
&pInfo->q, &pbExtra, &lRemainExtra);
|
|
Asn1X509GetHugeUINT(&pAsn1Info->g, dwFlags,
|
|
&pInfo->g, &pbExtra, &lRemainExtra);
|
|
|
|
*plRemainExtra = lRemainExtra;
|
|
return TRUE;
|
|
}
|
|
|
|
BOOL WINAPI Asn1X509DSSParametersDecodeEx(
|
|
IN DWORD dwCertEncodingType,
|
|
IN LPCSTR lpszStructType,
|
|
IN const BYTE *pbEncoded,
|
|
IN DWORD cbEncoded,
|
|
IN DWORD dwFlags,
|
|
IN OPTIONAL PCRYPT_DECODE_PARA pDecodePara,
|
|
OUT OPTIONAL void *pvStructInfo,
|
|
IN OUT DWORD *pcbStructInfo
|
|
)
|
|
{
|
|
return Asn1InfoDecodeAndAllocEx(
|
|
DSSParameters_PDU,
|
|
pbEncoded,
|
|
cbEncoded,
|
|
dwFlags,
|
|
pDecodePara,
|
|
Asn1X509DSSParametersDecodeExCallback,
|
|
pvStructInfo,
|
|
pcbStructInfo
|
|
);
|
|
}
|
|
|
|
//+-------------------------------------------------------------------------
|
|
// DSS Signature Encode (ASN1 X509)
|
|
//--------------------------------------------------------------------------
|
|
BOOL WINAPI Asn1X509DSSSignatureEncodeEx(
|
|
IN DWORD dwCertEncodingType,
|
|
IN LPCSTR lpszStructType,
|
|
IN BYTE rgbSignature[CERT_DSS_SIGNATURE_LEN],
|
|
IN DWORD dwFlags,
|
|
IN OPTIONAL PCRYPT_ENCODE_PARA pEncodePara,
|
|
OUT OPTIONAL void *pvEncoded,
|
|
IN OUT DWORD *pcbEncoded
|
|
)
|
|
{
|
|
BYTE rgbR[1 + CERT_DSS_R_LEN];
|
|
BYTE rgbS[1 + CERT_DSS_S_LEN];
|
|
DSSSignature Asn1Signature;
|
|
DWORD i;
|
|
|
|
// Treat the r and s components of the DSS signature as being unsigned.
|
|
// Also need to swap before doing the encode.
|
|
rgbR[0] = 0;
|
|
for (i = 0; i < CERT_DSS_R_LEN; i++)
|
|
rgbR[(1 + CERT_DSS_R_LEN - 1) - i] = rgbSignature[i];
|
|
Asn1Signature.r.length = sizeof(rgbR);
|
|
Asn1Signature.r.value = rgbR;
|
|
|
|
rgbS[0] = 0;
|
|
for (i = 0; i < CERT_DSS_S_LEN; i++)
|
|
rgbS[(1 + CERT_DSS_S_LEN - 1) - i] =
|
|
rgbSignature[CERT_DSS_R_LEN + i];
|
|
Asn1Signature.s.length = sizeof(rgbS);
|
|
Asn1Signature.s.value = rgbS;
|
|
|
|
return Asn1InfoEncodeEx(
|
|
DSSSignature_PDU,
|
|
&Asn1Signature,
|
|
dwFlags,
|
|
pEncodePara,
|
|
pvEncoded,
|
|
pcbEncoded
|
|
);
|
|
}
|
|
|
|
//+-------------------------------------------------------------------------
|
|
// DSS Signature Decode (ASN1 X509)
|
|
//--------------------------------------------------------------------------
|
|
BOOL WINAPI Asn1X509DSSSignatureDecodeExCallback(
|
|
IN void *pvAsn1Info,
|
|
IN DWORD dwFlags,
|
|
IN OPTIONAL PCRYPT_DECODE_PARA pDecodePara,
|
|
OUT OPTIONAL void *pvStructInfo,
|
|
IN OUT LONG *plRemainExtra
|
|
)
|
|
{
|
|
BOOL fResult;
|
|
DSSSignature *pAsn1Signature = (DSSSignature *) pvAsn1Info;
|
|
// BYTE rgbSignature[CERT_DSS_SIGNATURE_LEN],
|
|
BYTE *rgbSignature = (BYTE *) pvStructInfo;
|
|
DWORD cb;
|
|
BYTE *pb;
|
|
DWORD i;
|
|
|
|
*plRemainExtra -= CERT_DSS_SIGNATURE_LEN;
|
|
if (*plRemainExtra >= 0) {
|
|
memset(rgbSignature, 0, CERT_DSS_SIGNATURE_LEN);
|
|
|
|
// Strip off a leading 0 byte. Byte reverse while copying
|
|
cb = pAsn1Signature->r.length;
|
|
pb = pAsn1Signature->r.value;
|
|
if (cb > 1 && *pb == 0) {
|
|
pb++;
|
|
cb--;
|
|
}
|
|
if (0 == cb || cb > CERT_DSS_R_LEN)
|
|
goto DecodeError;
|
|
for (i = 0; i < cb; i++)
|
|
rgbSignature[i] = pb[cb - 1 - i];
|
|
|
|
// Strip off a leading 0 byte. Byte reverse while copying
|
|
cb = pAsn1Signature->s.length;
|
|
pb = pAsn1Signature->s.value;
|
|
if (cb > 1 && *pb == 0) {
|
|
pb++;
|
|
cb--;
|
|
}
|
|
if (0 == cb || cb > CERT_DSS_S_LEN)
|
|
goto DecodeError;
|
|
for (i = 0; i < cb; i++)
|
|
rgbSignature[CERT_DSS_R_LEN + i] = pb[cb - 1 - i];
|
|
}
|
|
|
|
fResult = TRUE;
|
|
CommonReturn:
|
|
return fResult;
|
|
|
|
ErrorReturn:
|
|
fResult = FALSE;
|
|
goto CommonReturn;
|
|
|
|
SET_ERROR(DecodeError, CRYPT_E_BAD_ENCODE)
|
|
}
|
|
|
|
BOOL WINAPI Asn1X509DSSSignatureDecodeEx(
|
|
IN DWORD dwCertEncodingType,
|
|
IN LPCSTR lpszStructType,
|
|
IN const BYTE *pbEncoded,
|
|
IN DWORD cbEncoded,
|
|
IN DWORD dwFlags,
|
|
IN OPTIONAL PCRYPT_DECODE_PARA pDecodePara,
|
|
OUT OPTIONAL void *pvStructInfo,
|
|
IN OUT DWORD *pcbStructInfo
|
|
)
|
|
{
|
|
return Asn1InfoDecodeAndAllocEx(
|
|
DSSSignature_PDU,
|
|
pbEncoded,
|
|
cbEncoded,
|
|
dwFlags,
|
|
pDecodePara,
|
|
Asn1X509DSSSignatureDecodeExCallback,
|
|
pvStructInfo,
|
|
pcbStructInfo
|
|
);
|
|
}
|
|
|
|
//+-------------------------------------------------------------------------
|
|
// DH Parameters Encode (ASN1 X509)
|
|
//--------------------------------------------------------------------------
|
|
BOOL WINAPI Asn1X509DHParametersEncodeEx(
|
|
IN DWORD dwCertEncodingType,
|
|
IN LPCSTR lpszStructType,
|
|
IN PCERT_DH_PARAMETERS pInfo,
|
|
IN DWORD dwFlags,
|
|
IN OPTIONAL PCRYPT_ENCODE_PARA pEncodePara,
|
|
OUT OPTIONAL void *pvEncoded,
|
|
IN OUT DWORD *pcbEncoded
|
|
)
|
|
{
|
|
BOOL fResult;
|
|
DHParameters Asn1Info;
|
|
|
|
memset(&Asn1Info, 0, sizeof(Asn1Info));
|
|
if (!Asn1X509SetHugeUINT(&pInfo->p, &Asn1Info.p))
|
|
goto ErrorReturn;
|
|
if (!Asn1X509SetHugeUINT(&pInfo->g, &Asn1Info.g))
|
|
goto ErrorReturn;
|
|
|
|
fResult = Asn1InfoEncodeEx(
|
|
DHParameters_PDU,
|
|
&Asn1Info,
|
|
dwFlags,
|
|
pEncodePara,
|
|
pvEncoded,
|
|
pcbEncoded
|
|
);
|
|
|
|
goto CommonReturn;
|
|
|
|
ErrorReturn:
|
|
if (dwFlags & CRYPT_ENCODE_ALLOC_FLAG)
|
|
*((void **) pvEncoded) = NULL;
|
|
*pcbEncoded = 0;
|
|
fResult = FALSE;
|
|
CommonReturn:
|
|
Asn1X509FreeHugeUINT(&Asn1Info.p);
|
|
Asn1X509FreeHugeUINT(&Asn1Info.g);
|
|
return fResult;
|
|
}
|
|
|
|
//+-------------------------------------------------------------------------
|
|
// DH Parameters Decode (ASN1 X509)
|
|
//--------------------------------------------------------------------------
|
|
BOOL WINAPI Asn1X509DHParametersDecodeExCallback(
|
|
IN void *pvAsn1Info,
|
|
IN DWORD dwFlags,
|
|
IN OPTIONAL PCRYPT_DECODE_PARA pDecodePara,
|
|
OUT OPTIONAL void *pvStructInfo,
|
|
IN OUT LONG *plRemainExtra
|
|
)
|
|
{
|
|
DHParameters *pAsn1Info = (DHParameters *) pvAsn1Info;
|
|
PCERT_DH_PARAMETERS pInfo = (PCERT_DH_PARAMETERS) pvStructInfo;
|
|
LONG lRemainExtra = *plRemainExtra;
|
|
BYTE *pbExtra;
|
|
|
|
lRemainExtra -= sizeof(CERT_DH_PARAMETERS);
|
|
if (lRemainExtra < 0) {
|
|
pbExtra = NULL;
|
|
} else
|
|
pbExtra = (BYTE *) pInfo + sizeof(CERT_DH_PARAMETERS);
|
|
|
|
Asn1X509GetHugeUINT(&pAsn1Info->p, dwFlags,
|
|
&pInfo->p, &pbExtra, &lRemainExtra);
|
|
Asn1X509GetHugeUINT(&pAsn1Info->g, dwFlags,
|
|
&pInfo->g, &pbExtra, &lRemainExtra);
|
|
|
|
*plRemainExtra = lRemainExtra;
|
|
return TRUE;
|
|
}
|
|
|
|
//+-------------------------------------------------------------------------
|
|
// DH Parameters Decode (ASN1) New Style X942
|
|
//--------------------------------------------------------------------------
|
|
BOOL WINAPI Asn1X509DHParametersX942DecodeExCallback(
|
|
IN void *pvAsn1Info,
|
|
IN DWORD dwFlags,
|
|
IN OPTIONAL PCRYPT_DECODE_PARA pDecodePara,
|
|
OUT OPTIONAL void *pvStructInfo,
|
|
IN OUT LONG *plRemainExtra
|
|
)
|
|
{
|
|
X942DhParameters *pAsn1Info = (X942DhParameters *) pvAsn1Info;
|
|
PCERT_DH_PARAMETERS pInfo = (PCERT_DH_PARAMETERS) pvStructInfo;
|
|
LONG lRemainExtra = *plRemainExtra;
|
|
BYTE *pbExtra;
|
|
|
|
lRemainExtra -= sizeof(CERT_DH_PARAMETERS);
|
|
if (lRemainExtra < 0) {
|
|
pbExtra = NULL;
|
|
} else
|
|
pbExtra = (BYTE *) pInfo + sizeof(CERT_DH_PARAMETERS);
|
|
|
|
Asn1X509GetHugeUINT(&pAsn1Info->p, dwFlags,
|
|
&pInfo->p, &pbExtra, &lRemainExtra);
|
|
Asn1X509GetHugeUINT(&pAsn1Info->g, dwFlags,
|
|
&pInfo->g, &pbExtra, &lRemainExtra);
|
|
|
|
*plRemainExtra = lRemainExtra;
|
|
return TRUE;
|
|
}
|
|
|
|
BOOL WINAPI Asn1X509DHParametersDecodeEx(
|
|
IN DWORD dwCertEncodingType,
|
|
IN LPCSTR lpszStructType,
|
|
IN const BYTE *pbEncoded,
|
|
IN DWORD cbEncoded,
|
|
IN DWORD dwFlags,
|
|
IN OPTIONAL PCRYPT_DECODE_PARA pDecodePara,
|
|
OUT OPTIONAL void *pvStructInfo,
|
|
IN OUT DWORD *pcbStructInfo
|
|
)
|
|
{
|
|
BOOL fResult;
|
|
DWORD cbStructInfo;
|
|
|
|
cbStructInfo = *pcbStructInfo;
|
|
fResult = Asn1InfoDecodeAndAllocEx(
|
|
DHParameters_PDU,
|
|
pbEncoded,
|
|
cbEncoded,
|
|
dwFlags,
|
|
pDecodePara,
|
|
Asn1X509DHParametersDecodeExCallback,
|
|
pvStructInfo,
|
|
&cbStructInfo
|
|
);
|
|
|
|
if (!fResult && 0 == cbStructInfo) {
|
|
// Try to decode as new style X942 parameters
|
|
|
|
DWORD dwErr = GetLastError();
|
|
|
|
cbStructInfo = *pcbStructInfo;
|
|
fResult = Asn1InfoDecodeAndAllocEx(
|
|
X942DhParameters_PDU,
|
|
pbEncoded,
|
|
cbEncoded,
|
|
dwFlags,
|
|
pDecodePara,
|
|
Asn1X509DHParametersX942DecodeExCallback,
|
|
pvStructInfo,
|
|
&cbStructInfo
|
|
);
|
|
if (!fResult && 0 == cbStructInfo)
|
|
SetLastError(dwErr);
|
|
}
|
|
|
|
*pcbStructInfo = cbStructInfo;
|
|
return fResult;
|
|
}
|
|
|
|
//+-------------------------------------------------------------------------
|
|
// X942 DH Parameters Encode (ASN1)
|
|
//--------------------------------------------------------------------------
|
|
BOOL WINAPI Asn1X942DhParametersEncodeEx(
|
|
IN DWORD dwCertEncodingType,
|
|
IN LPCSTR lpszStructType,
|
|
IN PCERT_X942_DH_PARAMETERS pInfo,
|
|
IN DWORD dwFlags,
|
|
IN OPTIONAL PCRYPT_ENCODE_PARA pEncodePara,
|
|
OUT OPTIONAL void *pvEncoded,
|
|
IN OUT DWORD *pcbEncoded
|
|
)
|
|
{
|
|
BOOL fResult;
|
|
X942DhParameters Asn1Info;
|
|
|
|
if (0 == pInfo->q.cbData) {
|
|
CERT_DH_PARAMETERS Pkcs3Info;
|
|
|
|
Pkcs3Info.p = pInfo->p;
|
|
Pkcs3Info.g = pInfo->g;
|
|
return Asn1X509DHParametersEncodeEx(
|
|
dwCertEncodingType,
|
|
lpszStructType,
|
|
&Pkcs3Info,
|
|
dwFlags,
|
|
pEncodePara,
|
|
pvEncoded,
|
|
pcbEncoded
|
|
);
|
|
}
|
|
|
|
memset(&Asn1Info, 0, sizeof(Asn1Info));
|
|
if (!Asn1X509SetHugeUINT(&pInfo->p, &Asn1Info.p))
|
|
goto ErrorReturn;
|
|
if (!Asn1X509SetHugeUINT(&pInfo->g, &Asn1Info.g))
|
|
goto ErrorReturn;
|
|
if (!Asn1X509SetHugeUINT(&pInfo->q, &Asn1Info.q))
|
|
goto ErrorReturn;
|
|
|
|
if (pInfo->j.cbData) {
|
|
if (!Asn1X509SetHugeUINT(&pInfo->j, &Asn1Info.j))
|
|
goto ErrorReturn;
|
|
Asn1Info.bit_mask |= j_present;
|
|
}
|
|
|
|
if (pInfo->pValidationParams) {
|
|
PCERT_X942_DH_VALIDATION_PARAMS pValidationParams =
|
|
pInfo->pValidationParams;
|
|
|
|
Asn1X509SetBit(&pValidationParams->seed,
|
|
&Asn1Info.validationParams.seed);
|
|
Asn1Info.validationParams.pgenCounter = pValidationParams->pgenCounter;
|
|
Asn1Info.bit_mask |= validationParams_present;
|
|
}
|
|
|
|
fResult = Asn1InfoEncodeEx(
|
|
X942DhParameters_PDU,
|
|
&Asn1Info,
|
|
dwFlags,
|
|
pEncodePara,
|
|
pvEncoded,
|
|
pcbEncoded
|
|
);
|
|
|
|
goto CommonReturn;
|
|
|
|
ErrorReturn:
|
|
if (dwFlags & CRYPT_ENCODE_ALLOC_FLAG)
|
|
*((void **) pvEncoded) = NULL;
|
|
*pcbEncoded = 0;
|
|
fResult = FALSE;
|
|
CommonReturn:
|
|
Asn1X509FreeHugeUINT(&Asn1Info.p);
|
|
Asn1X509FreeHugeUINT(&Asn1Info.g);
|
|
Asn1X509FreeHugeUINT(&Asn1Info.q);
|
|
Asn1X509FreeHugeUINT(&Asn1Info.j);
|
|
return fResult;
|
|
}
|
|
|
|
//+-------------------------------------------------------------------------
|
|
// X942 DH Parameters Decode (ASN1)
|
|
//--------------------------------------------------------------------------
|
|
BOOL WINAPI Asn1X942DhParametersDecodeExCallback(
|
|
IN void *pvAsn1Info,
|
|
IN DWORD dwFlags,
|
|
IN OPTIONAL PCRYPT_DECODE_PARA pDecodePara,
|
|
OUT OPTIONAL void *pvStructInfo,
|
|
IN OUT LONG *plRemainExtra
|
|
)
|
|
{
|
|
X942DhParameters *pAsn1Info = (X942DhParameters *) pvAsn1Info;
|
|
PCERT_X942_DH_PARAMETERS pInfo = (PCERT_X942_DH_PARAMETERS) pvStructInfo;
|
|
LONG lRemainExtra = *plRemainExtra;
|
|
BYTE *pbExtra;
|
|
|
|
lRemainExtra -= sizeof(CERT_X942_DH_PARAMETERS);
|
|
if (lRemainExtra < 0) {
|
|
pbExtra = NULL;
|
|
} else {
|
|
// Default all optional fields to zero
|
|
memset(pInfo, 0, sizeof(CERT_X942_DH_PARAMETERS));
|
|
|
|
pbExtra = (BYTE *) pInfo + sizeof(CERT_X942_DH_PARAMETERS);
|
|
}
|
|
|
|
Asn1X509GetHugeUINT(&pAsn1Info->p, dwFlags,
|
|
&pInfo->p, &pbExtra, &lRemainExtra);
|
|
Asn1X509GetHugeUINT(&pAsn1Info->g, dwFlags,
|
|
&pInfo->g, &pbExtra, &lRemainExtra);
|
|
Asn1X509GetHugeUINT(&pAsn1Info->q, dwFlags,
|
|
&pInfo->q, &pbExtra, &lRemainExtra);
|
|
|
|
if (pAsn1Info->bit_mask & j_present)
|
|
Asn1X509GetHugeUINT(&pAsn1Info->j, dwFlags,
|
|
&pInfo->j, &pbExtra, &lRemainExtra);
|
|
|
|
if (pAsn1Info->bit_mask & validationParams_present) {
|
|
PCERT_X942_DH_VALIDATION_PARAMS pValidationParams;
|
|
|
|
lRemainExtra -= sizeof(CERT_X942_DH_VALIDATION_PARAMS);
|
|
|
|
if (lRemainExtra < 0) {
|
|
pValidationParams = NULL;
|
|
} else {
|
|
pValidationParams = (PCERT_X942_DH_VALIDATION_PARAMS) pbExtra;
|
|
pInfo->pValidationParams = pValidationParams;
|
|
pbExtra += sizeof(CERT_X942_DH_VALIDATION_PARAMS);
|
|
pValidationParams->pgenCounter =
|
|
pAsn1Info->validationParams.pgenCounter;
|
|
}
|
|
|
|
Asn1X509GetBit(&pAsn1Info->validationParams.seed, dwFlags,
|
|
&pValidationParams->seed, &pbExtra, &lRemainExtra);
|
|
}
|
|
|
|
*plRemainExtra = lRemainExtra;
|
|
return TRUE;
|
|
}
|
|
|
|
//+-------------------------------------------------------------------------
|
|
// X942 DH Parameters Decode (ASN1) Old Style Pkcs #3
|
|
//--------------------------------------------------------------------------
|
|
BOOL WINAPI Asn1X942DhParametersPkcs3DecodeExCallback(
|
|
IN void *pvAsn1Info,
|
|
IN DWORD dwFlags,
|
|
IN OPTIONAL PCRYPT_DECODE_PARA pDecodePara,
|
|
OUT OPTIONAL void *pvStructInfo,
|
|
IN OUT LONG *plRemainExtra
|
|
)
|
|
{
|
|
DHParameters *pAsn1Info = (DHParameters *) pvAsn1Info;
|
|
PCERT_X942_DH_PARAMETERS pInfo = (PCERT_X942_DH_PARAMETERS) pvStructInfo;
|
|
LONG lRemainExtra = *plRemainExtra;
|
|
BYTE *pbExtra;
|
|
|
|
lRemainExtra -= sizeof(CERT_X942_DH_PARAMETERS);
|
|
if (lRemainExtra < 0) {
|
|
pbExtra = NULL;
|
|
} else {
|
|
// Default all optional fields to zero
|
|
memset(pInfo, 0, sizeof(CERT_X942_DH_PARAMETERS));
|
|
|
|
pbExtra = (BYTE *) pInfo + sizeof(CERT_X942_DH_PARAMETERS);
|
|
}
|
|
Asn1X509GetHugeUINT(&pAsn1Info->p, dwFlags,
|
|
&pInfo->p, &pbExtra, &lRemainExtra);
|
|
Asn1X509GetHugeUINT(&pAsn1Info->g, dwFlags,
|
|
&pInfo->g, &pbExtra, &lRemainExtra);
|
|
|
|
*plRemainExtra = lRemainExtra;
|
|
return TRUE;
|
|
}
|
|
|
|
BOOL WINAPI Asn1X942DhParametersDecodeEx(
|
|
IN DWORD dwCertEncodingType,
|
|
IN LPCSTR lpszStructType,
|
|
IN const BYTE *pbEncoded,
|
|
IN DWORD cbEncoded,
|
|
IN DWORD dwFlags,
|
|
IN OPTIONAL PCRYPT_DECODE_PARA pDecodePara,
|
|
OUT OPTIONAL void *pvStructInfo,
|
|
IN OUT DWORD *pcbStructInfo
|
|
)
|
|
{
|
|
BOOL fResult;
|
|
DWORD cbStructInfo;
|
|
|
|
cbStructInfo = *pcbStructInfo;
|
|
fResult = Asn1InfoDecodeAndAllocEx(
|
|
X942DhParameters_PDU,
|
|
pbEncoded,
|
|
cbEncoded,
|
|
dwFlags,
|
|
pDecodePara,
|
|
Asn1X942DhParametersDecodeExCallback,
|
|
pvStructInfo,
|
|
&cbStructInfo
|
|
);
|
|
|
|
if (!fResult && 0 == cbStructInfo) {
|
|
// Try to decode as old style PKCS #3 parameters
|
|
|
|
DWORD dwErr = GetLastError();
|
|
|
|
cbStructInfo = *pcbStructInfo;
|
|
fResult = Asn1InfoDecodeAndAllocEx(
|
|
DHParameters_PDU,
|
|
pbEncoded,
|
|
cbEncoded,
|
|
dwFlags,
|
|
pDecodePara,
|
|
Asn1X942DhParametersPkcs3DecodeExCallback,
|
|
pvStructInfo,
|
|
&cbStructInfo
|
|
);
|
|
if (!fResult && 0 == cbStructInfo)
|
|
SetLastError(dwErr);
|
|
}
|
|
|
|
*pcbStructInfo = cbStructInfo;
|
|
return fResult;
|
|
}
|
|
|
|
|
|
//+-------------------------------------------------------------------------
|
|
// X942_OTHER_INFO Encode (ASN1)
|
|
//--------------------------------------------------------------------------
|
|
BOOL WINAPI Asn1X942OtherInfoEncodeEx(
|
|
IN DWORD dwCertEncodingType,
|
|
IN LPCSTR lpszStructType,
|
|
IN PCRYPT_X942_OTHER_INFO pInfo,
|
|
IN DWORD dwFlags,
|
|
IN OPTIONAL PCRYPT_ENCODE_PARA pEncodePara,
|
|
OUT OPTIONAL void *pvEncoded,
|
|
IN OUT DWORD *pcbEncoded
|
|
)
|
|
{
|
|
BOOL fResult;
|
|
X942DhOtherInfo Asn1Info;
|
|
BYTE rgbAsn1Counter[CRYPT_X942_COUNTER_BYTE_LENGTH];
|
|
BYTE rgbAsn1KeyLength[CRYPT_X942_KEY_LENGTH_BYTE_LENGTH];
|
|
|
|
memset(&Asn1Info, 0, sizeof(Asn1Info));
|
|
if (!Asn1X509SetEncodedObjId(pInfo->pszContentEncryptionObjId,
|
|
&Asn1Info.keyInfo.algorithm))
|
|
goto ErrorReturn;
|
|
|
|
memcpy(rgbAsn1Counter, pInfo->rgbCounter, CRYPT_X942_COUNTER_BYTE_LENGTH);
|
|
PkiAsn1ReverseBytes(rgbAsn1Counter, CRYPT_X942_COUNTER_BYTE_LENGTH);
|
|
Asn1Info.keyInfo.counter.length = CRYPT_X942_COUNTER_BYTE_LENGTH;
|
|
Asn1Info.keyInfo.counter.value = rgbAsn1Counter;
|
|
|
|
memcpy(rgbAsn1KeyLength, pInfo->rgbKeyLength,
|
|
CRYPT_X942_KEY_LENGTH_BYTE_LENGTH);
|
|
PkiAsn1ReverseBytes(rgbAsn1KeyLength, CRYPT_X942_KEY_LENGTH_BYTE_LENGTH);
|
|
Asn1Info.keyLength.length = CRYPT_X942_KEY_LENGTH_BYTE_LENGTH;
|
|
Asn1Info.keyLength.value = rgbAsn1KeyLength;
|
|
|
|
if (pInfo->PubInfo.cbData) {
|
|
Asn1X509SetOctetString(&pInfo->PubInfo, &Asn1Info.pubInfo);
|
|
Asn1Info.bit_mask |= pubInfo_present;
|
|
}
|
|
|
|
fResult = Asn1InfoEncodeEx(
|
|
X942DhOtherInfo_PDU,
|
|
&Asn1Info,
|
|
dwFlags,
|
|
pEncodePara,
|
|
pvEncoded,
|
|
pcbEncoded
|
|
);
|
|
|
|
goto CommonReturn;
|
|
|
|
ErrorReturn:
|
|
if (dwFlags & CRYPT_ENCODE_ALLOC_FLAG)
|
|
*((void **) pvEncoded) = NULL;
|
|
*pcbEncoded = 0;
|
|
fResult = FALSE;
|
|
CommonReturn:
|
|
return fResult;
|
|
}
|
|
|
|
//+-------------------------------------------------------------------------
|
|
// X942_OTHER_INFO Decode (ASN1)
|
|
//--------------------------------------------------------------------------
|
|
BOOL WINAPI Asn1X942OtherInfoDecodeExCallback(
|
|
IN void *pvAsn1Info,
|
|
IN DWORD dwFlags,
|
|
IN OPTIONAL PCRYPT_DECODE_PARA pDecodePara,
|
|
OUT OPTIONAL void *pvStructInfo,
|
|
IN OUT LONG *plRemainExtra
|
|
)
|
|
{
|
|
X942DhOtherInfo *pAsn1Info = (X942DhOtherInfo *) pvAsn1Info;
|
|
PCRYPT_X942_OTHER_INFO pInfo = (PCRYPT_X942_OTHER_INFO) pvStructInfo;
|
|
LONG lRemainExtra = *plRemainExtra;
|
|
BYTE *pbExtra;
|
|
|
|
if (CRYPT_X942_COUNTER_BYTE_LENGTH != pAsn1Info->keyInfo.counter.length ||
|
|
CRYPT_X942_KEY_LENGTH_BYTE_LENGTH !=
|
|
pAsn1Info->keyLength.length) {
|
|
SetLastError((DWORD) CRYPT_E_BAD_ENCODE);
|
|
return FALSE;
|
|
}
|
|
|
|
lRemainExtra -= sizeof(CRYPT_X942_OTHER_INFO);
|
|
if (lRemainExtra < 0) {
|
|
pbExtra = NULL;
|
|
} else {
|
|
// Default all optional fields to zero
|
|
memset(pInfo, 0, sizeof(CRYPT_X942_OTHER_INFO));
|
|
|
|
memcpy(pInfo->rgbCounter, pAsn1Info->keyInfo.counter.value,
|
|
CRYPT_X942_COUNTER_BYTE_LENGTH);
|
|
PkiAsn1ReverseBytes(pInfo->rgbCounter, CRYPT_X942_COUNTER_BYTE_LENGTH);
|
|
|
|
memcpy(pInfo->rgbKeyLength, pAsn1Info->keyLength.value,
|
|
CRYPT_X942_KEY_LENGTH_BYTE_LENGTH);
|
|
PkiAsn1ReverseBytes(pInfo->rgbKeyLength,
|
|
CRYPT_X942_KEY_LENGTH_BYTE_LENGTH);
|
|
|
|
pbExtra = (BYTE *) pInfo + sizeof(CRYPT_X942_OTHER_INFO);
|
|
}
|
|
|
|
Asn1X509GetEncodedObjId(&pAsn1Info->keyInfo.algorithm, dwFlags,
|
|
&pInfo->pszContentEncryptionObjId,
|
|
&pbExtra, &lRemainExtra);
|
|
|
|
if (pAsn1Info->bit_mask & pubInfo_present) {
|
|
Asn1X509GetOctetString(&pAsn1Info->pubInfo, dwFlags,
|
|
&pInfo->PubInfo, &pbExtra, &lRemainExtra);
|
|
}
|
|
|
|
*plRemainExtra = lRemainExtra;
|
|
return TRUE;
|
|
}
|
|
|
|
BOOL WINAPI Asn1X942OtherInfoDecodeEx(
|
|
IN DWORD dwCertEncodingType,
|
|
IN LPCSTR lpszStructType,
|
|
IN const BYTE *pbEncoded,
|
|
IN DWORD cbEncoded,
|
|
IN DWORD dwFlags,
|
|
IN OPTIONAL PCRYPT_DECODE_PARA pDecodePara,
|
|
OUT OPTIONAL void *pvStructInfo,
|
|
IN OUT DWORD *pcbStructInfo
|
|
)
|
|
{
|
|
return Asn1InfoDecodeAndAllocEx(
|
|
X942DhOtherInfo_PDU,
|
|
pbEncoded,
|
|
cbEncoded,
|
|
dwFlags,
|
|
pDecodePara,
|
|
Asn1X942OtherInfoDecodeExCallback,
|
|
pvStructInfo,
|
|
pcbStructInfo
|
|
);
|
|
}
|
|
|
|
//+-------------------------------------------------------------------------
|
|
// RC2 CBC Parameters Encode (ASN1)
|
|
//--------------------------------------------------------------------------
|
|
BOOL WINAPI Asn1RC2CBCParametersEncodeEx(
|
|
IN DWORD dwCertEncodingType,
|
|
IN LPCSTR lpszStructType,
|
|
IN PCRYPT_RC2_CBC_PARAMETERS pInfo,
|
|
IN DWORD dwFlags,
|
|
IN OPTIONAL PCRYPT_ENCODE_PARA pEncodePara,
|
|
OUT OPTIONAL void *pvEncoded,
|
|
IN OUT DWORD *pcbEncoded
|
|
)
|
|
{
|
|
RC2CBCParameters Asn1Info;
|
|
|
|
memset(&Asn1Info, 0, sizeof(Asn1Info));
|
|
Asn1Info.version = pInfo->dwVersion;
|
|
if (pInfo->fIV) {
|
|
Asn1Info.bit_mask |= iv_present;
|
|
Asn1Info.iv.length = sizeof(pInfo->rgbIV);
|
|
Asn1Info.iv.value = pInfo->rgbIV;
|
|
}
|
|
|
|
return Asn1InfoEncodeEx(
|
|
RC2CBCParameters_PDU,
|
|
&Asn1Info,
|
|
dwFlags,
|
|
pEncodePara,
|
|
pvEncoded,
|
|
pcbEncoded
|
|
);
|
|
}
|
|
|
|
//+-------------------------------------------------------------------------
|
|
// RC2 CBC Parameters Decode (ASN1)
|
|
//--------------------------------------------------------------------------
|
|
BOOL WINAPI Asn1RC2CBCParametersDecodeExCallback(
|
|
IN void *pvAsn1Info,
|
|
IN DWORD dwFlags,
|
|
IN OPTIONAL PCRYPT_DECODE_PARA pDecodePara,
|
|
OUT OPTIONAL void *pvStructInfo,
|
|
IN OUT LONG *plRemainExtra
|
|
)
|
|
{
|
|
BOOL fResult;
|
|
RC2CBCParameters *pAsn1Info = (RC2CBCParameters *) pvAsn1Info;
|
|
PCRYPT_RC2_CBC_PARAMETERS pInfo = (PCRYPT_RC2_CBC_PARAMETERS) pvStructInfo;
|
|
|
|
*plRemainExtra -= sizeof(CRYPT_RC2_CBC_PARAMETERS);
|
|
if (*plRemainExtra >= 0) {
|
|
memset(pInfo, 0, sizeof(CRYPT_RC2_CBC_PARAMETERS));
|
|
pInfo->dwVersion = pAsn1Info->version;
|
|
if (pAsn1Info->bit_mask & iv_present) {
|
|
pInfo->fIV = TRUE;
|
|
if (pAsn1Info->iv.length != sizeof(pInfo->rgbIV))
|
|
goto DecodeError;
|
|
memcpy(pInfo->rgbIV, pAsn1Info->iv.value, sizeof(pInfo->rgbIV));
|
|
}
|
|
}
|
|
|
|
fResult = TRUE;
|
|
CommonReturn:
|
|
return fResult;
|
|
|
|
ErrorReturn:
|
|
fResult = FALSE;
|
|
goto CommonReturn;
|
|
|
|
SET_ERROR(DecodeError, CRYPT_E_BAD_ENCODE)
|
|
}
|
|
|
|
BOOL WINAPI Asn1RC2CBCParametersDecodeEx(
|
|
IN DWORD dwCertEncodingType,
|
|
IN LPCSTR lpszStructType,
|
|
IN const BYTE *pbEncoded,
|
|
IN DWORD cbEncoded,
|
|
IN DWORD dwFlags,
|
|
IN OPTIONAL PCRYPT_DECODE_PARA pDecodePara,
|
|
OUT OPTIONAL void *pvStructInfo,
|
|
IN OUT DWORD *pcbStructInfo
|
|
)
|
|
{
|
|
return Asn1InfoDecodeAndAllocEx(
|
|
RC2CBCParameters_PDU,
|
|
pbEncoded,
|
|
cbEncoded,
|
|
dwFlags,
|
|
pDecodePara,
|
|
Asn1RC2CBCParametersDecodeExCallback,
|
|
pvStructInfo,
|
|
pcbStructInfo
|
|
);
|
|
}
|
|
|
|
//+-------------------------------------------------------------------------
|
|
// SMIME Capabilities Encode (ASN1)
|
|
//--------------------------------------------------------------------------
|
|
BOOL WINAPI Asn1SMIMECapabilitiesEncodeEx(
|
|
IN DWORD dwCertEncodingType,
|
|
IN LPCSTR lpszStructType,
|
|
IN PCRYPT_SMIME_CAPABILITIES pInfo,
|
|
IN DWORD dwFlags,
|
|
IN OPTIONAL PCRYPT_ENCODE_PARA pEncodePara,
|
|
OUT OPTIONAL void *pvEncoded,
|
|
IN OUT DWORD *pcbEncoded
|
|
)
|
|
{
|
|
BOOL fResult;
|
|
SMIMECapabilities Asn1Info;
|
|
|
|
memset(&Asn1Info, 0, sizeof(Asn1Info));
|
|
if (0 != pInfo->cCapability) {
|
|
DWORD cCap = pInfo->cCapability;
|
|
PCRYPT_SMIME_CAPABILITY pCap = pInfo->rgCapability;
|
|
SMIMECapability *pAsn1Cap;
|
|
|
|
if (NULL == (pAsn1Cap = (SMIMECapability *) PkiZeroAlloc(
|
|
cCap * sizeof(SMIMECapability))))
|
|
goto ErrorReturn;
|
|
|
|
Asn1Info.count = cCap;
|
|
Asn1Info.value = pAsn1Cap;
|
|
for ( ; cCap > 0; cCap--, pCap++, pAsn1Cap++) {
|
|
if (!Asn1X509SetEncodedObjId(pCap->pszObjId, &pAsn1Cap->capabilityID))
|
|
goto ErrorReturn;
|
|
if (pCap->Parameters.cbData) {
|
|
pAsn1Cap->bit_mask |= smimeParameters_present;
|
|
Asn1X509SetAny(&pCap->Parameters,
|
|
&pAsn1Cap->smimeParameters);
|
|
}
|
|
}
|
|
}
|
|
|
|
fResult = Asn1InfoEncodeEx(
|
|
SMIMECapabilities_PDU,
|
|
&Asn1Info,
|
|
dwFlags,
|
|
pEncodePara,
|
|
pvEncoded,
|
|
pcbEncoded
|
|
);
|
|
|
|
goto CommonReturn;
|
|
|
|
ErrorReturn:
|
|
if (dwFlags & CRYPT_ENCODE_ALLOC_FLAG)
|
|
*((void **) pvEncoded) = NULL;
|
|
*pcbEncoded = 0;
|
|
fResult = FALSE;
|
|
CommonReturn:
|
|
PkiFree(Asn1Info.value);
|
|
return fResult;
|
|
}
|
|
|
|
//+-------------------------------------------------------------------------
|
|
// SMIME Capabilities Decode (ASN1)
|
|
//--------------------------------------------------------------------------
|
|
BOOL WINAPI Asn1SMIMECapabilitiesDecodeExCallback(
|
|
IN void *pvAsn1Info,
|
|
IN DWORD dwFlags,
|
|
IN OPTIONAL PCRYPT_DECODE_PARA pDecodePara,
|
|
OUT OPTIONAL void *pvStructInfo,
|
|
IN OUT LONG *plRemainExtra
|
|
)
|
|
{
|
|
SMIMECapabilities *pAsn1Info = (SMIMECapabilities *) pvAsn1Info;
|
|
PCRYPT_SMIME_CAPABILITIES pInfo = (PCRYPT_SMIME_CAPABILITIES) pvStructInfo;
|
|
LONG lRemainExtra = *plRemainExtra;
|
|
BYTE *pbExtra;
|
|
LONG lAlignExtra;
|
|
DWORD cCap;
|
|
SMIMECapability *pAsn1Cap;
|
|
PCRYPT_SMIME_CAPABILITY pCap;
|
|
|
|
cCap = pAsn1Info->count;
|
|
lAlignExtra = cCap * sizeof(CRYPT_SMIME_CAPABILITY);
|
|
|
|
lRemainExtra -= sizeof(CRYPT_SMIME_CAPABILITIES) + lAlignExtra;
|
|
if (lRemainExtra < 0) {
|
|
pbExtra = NULL;
|
|
pCap = NULL;
|
|
} else {
|
|
pbExtra = (BYTE *) pInfo + sizeof(CRYPT_SMIME_CAPABILITIES);
|
|
pCap = (PCRYPT_SMIME_CAPABILITY) pbExtra;
|
|
pInfo->cCapability = cCap;
|
|
pInfo->rgCapability = pCap;
|
|
if (lAlignExtra) {
|
|
memset(pbExtra, 0, lAlignExtra);
|
|
pbExtra += lAlignExtra;
|
|
}
|
|
}
|
|
|
|
pAsn1Cap = pAsn1Info->value;
|
|
for ( ; cCap > 0; cCap--, pAsn1Cap++, pCap++) {
|
|
Asn1X509GetEncodedObjId(&pAsn1Cap->capabilityID, dwFlags, &pCap->pszObjId,
|
|
&pbExtra, &lRemainExtra);
|
|
if (pAsn1Cap->bit_mask & smimeParameters_present)
|
|
Asn1X509GetAny(&pAsn1Cap->smimeParameters, dwFlags,
|
|
&pCap->Parameters, &pbExtra, &lRemainExtra);
|
|
}
|
|
|
|
*plRemainExtra = lRemainExtra;
|
|
return TRUE;
|
|
}
|
|
|
|
BOOL WINAPI Asn1SMIMECapabilitiesDecodeEx(
|
|
IN DWORD dwCertEncodingType,
|
|
IN LPCSTR lpszStructType,
|
|
IN const BYTE *pbEncoded,
|
|
IN DWORD cbEncoded,
|
|
IN DWORD dwFlags,
|
|
IN OPTIONAL PCRYPT_DECODE_PARA pDecodePara,
|
|
OUT OPTIONAL void *pvStructInfo,
|
|
IN OUT DWORD *pcbStructInfo
|
|
)
|
|
{
|
|
return Asn1InfoDecodeAndAllocEx(
|
|
SMIMECapabilities_PDU,
|
|
pbEncoded,
|
|
cbEncoded,
|
|
dwFlags,
|
|
pDecodePara,
|
|
Asn1SMIMECapabilitiesDecodeExCallback,
|
|
pvStructInfo,
|
|
pcbStructInfo
|
|
);
|
|
}
|
|
|
|
//+-------------------------------------------------------------------------
|
|
// Enumerated Extension Encode (ASN1 X509)
|
|
//--------------------------------------------------------------------------
|
|
BOOL WINAPI Asn1X509EnumeratedEncodeEx(
|
|
IN DWORD dwCertEncodingType,
|
|
IN LPCSTR lpszStructType,
|
|
IN int *pInfo,
|
|
IN DWORD dwFlags,
|
|
IN OPTIONAL PCRYPT_ENCODE_PARA pEncodePara,
|
|
OUT OPTIONAL void *pvEncoded,
|
|
IN OUT DWORD *pcbEncoded
|
|
)
|
|
{
|
|
EnumeratedType Asn1Info = (EnumeratedType) *pInfo;
|
|
|
|
return Asn1InfoEncodeEx(
|
|
EnumeratedType_PDU,
|
|
&Asn1Info,
|
|
dwFlags,
|
|
pEncodePara,
|
|
pvEncoded,
|
|
pcbEncoded
|
|
);
|
|
}
|
|
|
|
//+-------------------------------------------------------------------------
|
|
// Enumerated Extension Decode (ASN1 X509)
|
|
//--------------------------------------------------------------------------
|
|
BOOL WINAPI Asn1X509EnumeratedDecodeExCallback(
|
|
IN void *pvAsn1Info,
|
|
IN DWORD dwFlags,
|
|
IN OPTIONAL PCRYPT_DECODE_PARA pDecodePara,
|
|
OUT OPTIONAL void *pvStructInfo,
|
|
IN OUT LONG *plRemainExtra
|
|
)
|
|
{
|
|
EnumeratedType *pAsn1Info = (EnumeratedType *) pvAsn1Info;
|
|
int *pInfo = (int *) pvStructInfo;
|
|
|
|
*plRemainExtra -= sizeof(int);
|
|
if (*plRemainExtra >= 0)
|
|
*pInfo = *pAsn1Info;
|
|
return TRUE;
|
|
}
|
|
|
|
BOOL WINAPI Asn1X509EnumeratedDecodeEx(
|
|
IN DWORD dwCertEncodingType,
|
|
IN LPCSTR lpszStructType,
|
|
IN const BYTE *pbEncoded,
|
|
IN DWORD cbEncoded,
|
|
IN DWORD dwFlags,
|
|
IN OPTIONAL PCRYPT_DECODE_PARA pDecodePara,
|
|
OUT OPTIONAL void *pvStructInfo,
|
|
IN OUT DWORD *pcbStructInfo
|
|
)
|
|
{
|
|
return Asn1InfoDecodeAndAllocEx(
|
|
EnumeratedType_PDU,
|
|
pbEncoded,
|
|
cbEncoded,
|
|
dwFlags,
|
|
pDecodePara,
|
|
Asn1X509EnumeratedDecodeExCallback,
|
|
pvStructInfo,
|
|
pcbStructInfo
|
|
);
|
|
}
|
|
|
|
//+-------------------------------------------------------------------------
|
|
// Octet String Extension Encode (ASN1 X509)
|
|
//--------------------------------------------------------------------------
|
|
BOOL WINAPI Asn1X509OctetStringEncodeEx(
|
|
IN DWORD dwCertEncodingType,
|
|
IN LPCSTR lpszStructType,
|
|
IN PCRYPT_DATA_BLOB pInfo,
|
|
IN DWORD dwFlags,
|
|
IN OPTIONAL PCRYPT_ENCODE_PARA pEncodePara,
|
|
OUT OPTIONAL void *pvEncoded,
|
|
IN OUT DWORD *pcbEncoded
|
|
)
|
|
{
|
|
OCTETSTRING Asn1Info;
|
|
|
|
Asn1X509SetOctetString(pInfo, &Asn1Info);
|
|
return Asn1InfoEncodeEx(
|
|
OctetStringType_PDU,
|
|
&Asn1Info,
|
|
dwFlags,
|
|
pEncodePara,
|
|
pvEncoded,
|
|
pcbEncoded
|
|
);
|
|
}
|
|
|
|
//+-------------------------------------------------------------------------
|
|
// Octet String Extension Decode (ASN1 X509)
|
|
//--------------------------------------------------------------------------
|
|
BOOL WINAPI Asn1X509OctetStringDecodeExCallback(
|
|
IN void *pvAsn1Info,
|
|
IN DWORD dwFlags,
|
|
IN OPTIONAL PCRYPT_DECODE_PARA pDecodePara,
|
|
OUT OPTIONAL void *pvStructInfo,
|
|
IN OUT LONG *plRemainExtra
|
|
)
|
|
{
|
|
OCTETSTRING *pAsn1Info = (OCTETSTRING *) pvAsn1Info;
|
|
PCRYPT_DATA_BLOB pInfo = (PCRYPT_DATA_BLOB) pvStructInfo;
|
|
LONG lRemainExtra = *plRemainExtra;
|
|
BYTE *pbExtra;
|
|
|
|
lRemainExtra -= sizeof(CRYPT_DATA_BLOB);
|
|
if (lRemainExtra < 0) {
|
|
pbExtra = NULL;
|
|
} else
|
|
pbExtra = (BYTE *) pInfo + sizeof(CRYPT_DATA_BLOB);
|
|
|
|
Asn1X509GetOctetString(pAsn1Info, dwFlags, pInfo, &pbExtra, &lRemainExtra);
|
|
|
|
*plRemainExtra = lRemainExtra;
|
|
return TRUE;
|
|
}
|
|
|
|
BOOL WINAPI Asn1X509OctetStringDecodeEx(
|
|
IN DWORD dwCertEncodingType,
|
|
IN LPCSTR lpszStructType,
|
|
IN const BYTE *pbEncoded,
|
|
IN DWORD cbEncoded,
|
|
IN DWORD dwFlags,
|
|
IN OPTIONAL PCRYPT_DECODE_PARA pDecodePara,
|
|
OUT OPTIONAL void *pvStructInfo,
|
|
IN OUT DWORD *pcbStructInfo
|
|
)
|
|
{
|
|
return Asn1InfoDecodeAndAllocEx(
|
|
OctetStringType_PDU,
|
|
pbEncoded,
|
|
cbEncoded,
|
|
dwFlags,
|
|
pDecodePara,
|
|
Asn1X509OctetStringDecodeExCallback,
|
|
pvStructInfo,
|
|
pcbStructInfo
|
|
);
|
|
}
|
|
|
|
//+-------------------------------------------------------------------------
|
|
// ChoiceOfTime Extension Encode (ASN1 X509)
|
|
//--------------------------------------------------------------------------
|
|
BOOL WINAPI Asn1X509ChoiceOfTimeEncodeEx(
|
|
IN DWORD dwCertEncodingType,
|
|
IN LPCSTR lpszStructType,
|
|
IN LPFILETIME pInfo,
|
|
IN DWORD dwFlags,
|
|
IN OPTIONAL PCRYPT_ENCODE_PARA pEncodePara,
|
|
OUT OPTIONAL void *pvEncoded,
|
|
IN OUT DWORD *pcbEncoded
|
|
)
|
|
{
|
|
ChoiceOfTime Asn1Info;
|
|
|
|
if (!PkiAsn1ToChoiceOfTime(pInfo,
|
|
&Asn1Info.choice,
|
|
&Asn1Info.u.generalTime ,
|
|
&Asn1Info.u.utcTime
|
|
)) {
|
|
SetLastError((DWORD) CRYPT_E_BAD_ENCODE);
|
|
if (dwFlags & CRYPT_ENCODE_ALLOC_FLAG)
|
|
*((void **) pvEncoded) = NULL;
|
|
*pcbEncoded = 0;
|
|
return FALSE;
|
|
}
|
|
return Asn1InfoEncodeEx(
|
|
ChoiceOfTime_PDU,
|
|
&Asn1Info,
|
|
dwFlags,
|
|
pEncodePara,
|
|
pvEncoded,
|
|
pcbEncoded
|
|
);
|
|
}
|
|
|
|
//+-------------------------------------------------------------------------
|
|
// ChoiceOfTime Extension Decode (ASN1 X509)
|
|
//--------------------------------------------------------------------------
|
|
BOOL WINAPI Asn1X509ChoiceOfTimeDecodeExCallback(
|
|
IN void *pvAsn1Info,
|
|
IN DWORD dwFlags,
|
|
IN OPTIONAL PCRYPT_DECODE_PARA pDecodePara,
|
|
OUT OPTIONAL void *pvStructInfo,
|
|
IN OUT LONG *plRemainExtra
|
|
)
|
|
{
|
|
BOOL fResult;
|
|
ChoiceOfTime *pAsn1Info = (ChoiceOfTime *) pvAsn1Info;
|
|
LPFILETIME pInfo = (LPFILETIME) pvStructInfo;
|
|
|
|
*plRemainExtra -= sizeof(FILETIME);
|
|
if (*plRemainExtra >= 0) {
|
|
if (!PkiAsn1FromChoiceOfTime(pAsn1Info->choice,
|
|
&pAsn1Info->u.generalTime,
|
|
&pAsn1Info->u.utcTime,
|
|
pInfo))
|
|
goto DecodeError;
|
|
}
|
|
|
|
fResult = TRUE;
|
|
CommonReturn:
|
|
return fResult;
|
|
|
|
ErrorReturn:
|
|
fResult = FALSE;
|
|
goto CommonReturn;
|
|
|
|
SET_ERROR(DecodeError, CRYPT_E_BAD_ENCODE)
|
|
}
|
|
|
|
BOOL WINAPI Asn1X509ChoiceOfTimeDecodeEx(
|
|
IN DWORD dwCertEncodingType,
|
|
IN LPCSTR lpszStructType,
|
|
IN const BYTE *pbEncoded,
|
|
IN DWORD cbEncoded,
|
|
IN DWORD dwFlags,
|
|
IN OPTIONAL PCRYPT_DECODE_PARA pDecodePara,
|
|
OUT OPTIONAL void *pvStructInfo,
|
|
IN OUT DWORD *pcbStructInfo
|
|
)
|
|
{
|
|
return Asn1InfoDecodeAndAllocEx(
|
|
ChoiceOfTime_PDU,
|
|
pbEncoded,
|
|
cbEncoded,
|
|
dwFlags,
|
|
pDecodePara,
|
|
Asn1X509ChoiceOfTimeDecodeExCallback,
|
|
pvStructInfo,
|
|
pcbStructInfo
|
|
);
|
|
}
|
|
|
|
|
|
//+-------------------------------------------------------------------------
|
|
// Attribute Encode (ASN1 X509)
|
|
//--------------------------------------------------------------------------
|
|
BOOL WINAPI Asn1X509AttributeEncodeEx(
|
|
IN DWORD dwCertEncodingType,
|
|
IN LPCSTR lpszStructType,
|
|
IN PCRYPT_ATTRIBUTE pInfo,
|
|
IN DWORD dwFlags,
|
|
IN OPTIONAL PCRYPT_ENCODE_PARA pEncodePara,
|
|
OUT OPTIONAL void *pvEncoded,
|
|
IN OUT DWORD *pcbEncoded
|
|
)
|
|
{
|
|
BOOL fResult;
|
|
Attribute Asn1Info;
|
|
|
|
|
|
if (!Asn1X509SetAttribute(pInfo, &Asn1Info)) {
|
|
if (dwFlags & CRYPT_ENCODE_ALLOC_FLAG)
|
|
*((void **) pvEncoded) = NULL;
|
|
*pcbEncoded = 0;
|
|
return FALSE;
|
|
}
|
|
fResult = Asn1InfoEncodeEx(
|
|
Attribute_PDU,
|
|
&Asn1Info,
|
|
dwFlags,
|
|
pEncodePara,
|
|
pvEncoded,
|
|
pcbEncoded
|
|
);
|
|
Asn1X509FreeAttribute(&Asn1Info);
|
|
return fResult;
|
|
}
|
|
|
|
//+-------------------------------------------------------------------------
|
|
// Attribute Decode (ASN1 X509)
|
|
//--------------------------------------------------------------------------
|
|
BOOL WINAPI Asn1X509AttributeDecodeExCallback(
|
|
IN void *pvAsn1Info,
|
|
IN DWORD dwFlags,
|
|
IN OPTIONAL PCRYPT_DECODE_PARA pDecodePara,
|
|
OUT OPTIONAL void *pvStructInfo,
|
|
IN OUT LONG *plRemainExtra
|
|
)
|
|
{
|
|
Attribute *pAsn1Info = (Attribute *) pvAsn1Info;
|
|
PCRYPT_ATTRIBUTE pInfo = (PCRYPT_ATTRIBUTE) pvStructInfo;
|
|
LONG lRemainExtra = *plRemainExtra;
|
|
BYTE *pbExtra;
|
|
|
|
lRemainExtra -= sizeof(CRYPT_ATTRIBUTE);
|
|
if (lRemainExtra < 0) {
|
|
pbExtra = NULL;
|
|
} else
|
|
pbExtra = (BYTE *) pInfo + sizeof(CRYPT_ATTRIBUTE);
|
|
|
|
Asn1X509GetAttribute(pAsn1Info, dwFlags, pInfo, &pbExtra, &lRemainExtra);
|
|
|
|
*plRemainExtra = lRemainExtra;
|
|
return TRUE;
|
|
}
|
|
|
|
BOOL WINAPI Asn1X509AttributeDecodeEx(
|
|
IN DWORD dwCertEncodingType,
|
|
IN LPCSTR lpszStructType,
|
|
IN const BYTE *pbEncoded,
|
|
IN DWORD cbEncoded,
|
|
IN DWORD dwFlags,
|
|
IN OPTIONAL PCRYPT_DECODE_PARA pDecodePara,
|
|
OUT OPTIONAL void *pvStructInfo,
|
|
IN OUT DWORD *pcbStructInfo
|
|
)
|
|
{
|
|
return Asn1InfoDecodeAndAllocEx(
|
|
Attribute_PDU,
|
|
pbEncoded,
|
|
cbEncoded,
|
|
dwFlags,
|
|
pDecodePara,
|
|
Asn1X509AttributeDecodeExCallback,
|
|
pvStructInfo,
|
|
pcbStructInfo
|
|
);
|
|
}
|
|
|
|
|
|
//+-------------------------------------------------------------------------
|
|
// ContentInfo Encode (ASN1 X509)
|
|
//--------------------------------------------------------------------------
|
|
BOOL WINAPI Asn1X509ContentInfoEncodeEx(
|
|
IN DWORD dwCertEncodingType,
|
|
IN LPCSTR lpszStructType,
|
|
IN PCRYPT_CONTENT_INFO pInfo,
|
|
IN DWORD dwFlags,
|
|
IN OPTIONAL PCRYPT_ENCODE_PARA pEncodePara,
|
|
OUT OPTIONAL void *pvEncoded,
|
|
IN OUT DWORD *pcbEncoded
|
|
)
|
|
{
|
|
ContentInfo Asn1Info;
|
|
|
|
memset(&Asn1Info, 0, sizeof(Asn1Info));
|
|
if (!Asn1X509SetEncodedObjId(pInfo->pszObjId, &Asn1Info.contentType)) {
|
|
if (dwFlags & CRYPT_ENCODE_ALLOC_FLAG)
|
|
*((void **) pvEncoded) = NULL;
|
|
*pcbEncoded = 0;
|
|
return FALSE;
|
|
}
|
|
|
|
if (pInfo->Content.cbData) {
|
|
Asn1Info.bit_mask |= content_present;
|
|
Asn1X509SetAny(&pInfo->Content, &Asn1Info.content);
|
|
}
|
|
|
|
return Asn1InfoEncodeEx(
|
|
ContentInfo_PDU,
|
|
&Asn1Info,
|
|
dwFlags,
|
|
pEncodePara,
|
|
pvEncoded,
|
|
pcbEncoded
|
|
);
|
|
}
|
|
|
|
//+-------------------------------------------------------------------------
|
|
// ContentInfo Decode (ASN1 X509)
|
|
//--------------------------------------------------------------------------
|
|
BOOL WINAPI Asn1X509ContentInfoDecodeExCallback(
|
|
IN void *pvAsn1Info,
|
|
IN DWORD dwFlags,
|
|
IN OPTIONAL PCRYPT_DECODE_PARA pDecodePara,
|
|
OUT OPTIONAL void *pvStructInfo,
|
|
IN OUT LONG *plRemainExtra
|
|
)
|
|
{
|
|
ContentInfo *pAsn1Info = (ContentInfo *) pvAsn1Info;
|
|
PCRYPT_CONTENT_INFO pInfo = (PCRYPT_CONTENT_INFO) pvStructInfo;
|
|
LONG lRemainExtra = *plRemainExtra;
|
|
BYTE *pbExtra;
|
|
|
|
lRemainExtra -= sizeof(CRYPT_CONTENT_INFO);
|
|
if (lRemainExtra < 0) {
|
|
pbExtra = NULL;
|
|
} else {
|
|
memset(pInfo, 0, sizeof(CRYPT_CONTENT_INFO));
|
|
pbExtra = (BYTE *) pInfo + sizeof(CRYPT_CONTENT_INFO);
|
|
}
|
|
|
|
Asn1X509GetEncodedObjId(&pAsn1Info->contentType, dwFlags,
|
|
&pInfo->pszObjId, &pbExtra, &lRemainExtra);
|
|
if (pAsn1Info->bit_mask & content_present)
|
|
Asn1X509GetAny(&pAsn1Info->content, dwFlags,
|
|
&pInfo->Content, &pbExtra, &lRemainExtra);
|
|
|
|
*plRemainExtra = lRemainExtra;
|
|
return TRUE;
|
|
}
|
|
|
|
BOOL WINAPI Asn1X509ContentInfoDecodeEx(
|
|
IN DWORD dwCertEncodingType,
|
|
IN LPCSTR lpszStructType,
|
|
IN const BYTE *pbEncoded,
|
|
IN DWORD cbEncoded,
|
|
IN DWORD dwFlags,
|
|
IN OPTIONAL PCRYPT_DECODE_PARA pDecodePara,
|
|
OUT OPTIONAL void *pvStructInfo,
|
|
IN OUT DWORD *pcbStructInfo
|
|
)
|
|
{
|
|
return Asn1InfoDecodeAndAllocEx(
|
|
ContentInfo_PDU,
|
|
pbEncoded,
|
|
cbEncoded,
|
|
dwFlags,
|
|
pDecodePara,
|
|
Asn1X509ContentInfoDecodeExCallback,
|
|
pvStructInfo,
|
|
pcbStructInfo
|
|
);
|
|
}
|
|
|
|
|
|
//+-------------------------------------------------------------------------
|
|
// ContentInfoSequenceOfAny Encode (ASN1 X509)
|
|
//--------------------------------------------------------------------------
|
|
BOOL WINAPI Asn1X509ContentInfoSequenceOfAnyEncodeEx(
|
|
IN DWORD dwCertEncodingType,
|
|
IN LPCSTR lpszStructType,
|
|
IN PCRYPT_CONTENT_INFO_SEQUENCE_OF_ANY pInfo,
|
|
IN DWORD dwFlags,
|
|
IN OPTIONAL PCRYPT_ENCODE_PARA pEncodePara,
|
|
OUT OPTIONAL void *pvEncoded,
|
|
IN OUT DWORD *pcbEncoded
|
|
)
|
|
{
|
|
BOOL fResult;
|
|
ContentInfoSeqOfAny Asn1Info;
|
|
|
|
memset(&Asn1Info, 0, sizeof(Asn1Info));
|
|
if (!Asn1X509SetEncodedObjId(pInfo->pszObjId, &Asn1Info.contentType))
|
|
goto ErrorReturn;
|
|
|
|
if (pInfo->cValue) {
|
|
Asn1Info.bit_mask |= contentSeqOfAny_present;
|
|
if (!Asn1X509SetSeqOfAny(
|
|
pInfo->cValue,
|
|
pInfo->rgValue,
|
|
&Asn1Info.contentSeqOfAny.count,
|
|
&Asn1Info.contentSeqOfAny.value))
|
|
goto ErrorReturn;
|
|
}
|
|
|
|
fResult = Asn1InfoEncodeEx(
|
|
ContentInfoSeqOfAny_PDU,
|
|
&Asn1Info,
|
|
dwFlags,
|
|
pEncodePara,
|
|
pvEncoded,
|
|
pcbEncoded
|
|
);
|
|
|
|
goto CommonReturn;
|
|
|
|
ErrorReturn:
|
|
if (dwFlags & CRYPT_ENCODE_ALLOC_FLAG)
|
|
*((void **) pvEncoded) = NULL;
|
|
*pcbEncoded = 0;
|
|
fResult = FALSE;
|
|
CommonReturn:
|
|
Asn1X509FreeSeqOfAny(Asn1Info.contentSeqOfAny.value);
|
|
return fResult;
|
|
}
|
|
|
|
//+-------------------------------------------------------------------------
|
|
// ContentInfoSequenceOfAny Decode (ASN1 X509)
|
|
//--------------------------------------------------------------------------
|
|
BOOL WINAPI Asn1X509ContentInfoSequenceOfAnyDecodeExCallback(
|
|
IN void *pvAsn1Info,
|
|
IN DWORD dwFlags,
|
|
IN OPTIONAL PCRYPT_DECODE_PARA pDecodePara,
|
|
OUT OPTIONAL void *pvStructInfo,
|
|
IN OUT LONG *plRemainExtra
|
|
)
|
|
{
|
|
ContentInfoSeqOfAny *pAsn1Info = (ContentInfoSeqOfAny *) pvAsn1Info;
|
|
PCRYPT_CONTENT_INFO_SEQUENCE_OF_ANY pInfo =
|
|
(PCRYPT_CONTENT_INFO_SEQUENCE_OF_ANY) pvStructInfo;
|
|
LONG lRemainExtra = *plRemainExtra;
|
|
BYTE *pbExtra;
|
|
|
|
lRemainExtra -= sizeof(CRYPT_CONTENT_INFO_SEQUENCE_OF_ANY);
|
|
if (lRemainExtra < 0) {
|
|
pbExtra = NULL;
|
|
} else {
|
|
memset(pInfo, 0, sizeof(CRYPT_CONTENT_INFO_SEQUENCE_OF_ANY));
|
|
pbExtra = (BYTE *) pInfo + sizeof(CRYPT_CONTENT_INFO_SEQUENCE_OF_ANY);
|
|
}
|
|
|
|
Asn1X509GetEncodedObjId(&pAsn1Info->contentType, dwFlags,
|
|
&pInfo->pszObjId, &pbExtra, &lRemainExtra);
|
|
if (pAsn1Info->bit_mask & contentSeqOfAny_present)
|
|
Asn1X509GetSeqOfAny(pAsn1Info->contentSeqOfAny.count,
|
|
pAsn1Info->contentSeqOfAny.value, dwFlags,
|
|
&pInfo->cValue, &pInfo->rgValue, &pbExtra, &lRemainExtra);
|
|
|
|
*plRemainExtra = lRemainExtra;
|
|
return TRUE;
|
|
}
|
|
|
|
BOOL WINAPI Asn1X509ContentInfoSequenceOfAnyDecodeEx(
|
|
IN DWORD dwCertEncodingType,
|
|
IN LPCSTR lpszStructType,
|
|
IN const BYTE *pbEncoded,
|
|
IN DWORD cbEncoded,
|
|
IN DWORD dwFlags,
|
|
IN OPTIONAL PCRYPT_DECODE_PARA pDecodePara,
|
|
OUT OPTIONAL void *pvStructInfo,
|
|
IN OUT DWORD *pcbStructInfo
|
|
)
|
|
{
|
|
return Asn1InfoDecodeAndAllocEx(
|
|
ContentInfoSeqOfAny_PDU,
|
|
pbEncoded,
|
|
cbEncoded,
|
|
dwFlags,
|
|
pDecodePara,
|
|
Asn1X509ContentInfoSequenceOfAnyDecodeExCallback,
|
|
pvStructInfo,
|
|
pcbStructInfo
|
|
);
|
|
}
|
|
|
|
//+-------------------------------------------------------------------------
|
|
// SequenceOfAny Encode (ASN1 X509)
|
|
//--------------------------------------------------------------------------
|
|
BOOL WINAPI Asn1X509SequenceOfAnyEncodeEx(
|
|
IN DWORD dwCertEncodingType,
|
|
IN LPCSTR lpszStructType,
|
|
IN PCRYPT_SEQUENCE_OF_ANY pInfo,
|
|
IN DWORD dwFlags,
|
|
IN OPTIONAL PCRYPT_ENCODE_PARA pEncodePara,
|
|
OUT OPTIONAL void *pvEncoded,
|
|
IN OUT DWORD *pcbEncoded
|
|
)
|
|
{
|
|
BOOL fResult;
|
|
SeqOfAny Asn1Info;
|
|
|
|
if (!Asn1X509SetSeqOfAny(
|
|
pInfo->cValue,
|
|
pInfo->rgValue,
|
|
&Asn1Info.count,
|
|
&Asn1Info.value))
|
|
goto ErrorReturn;
|
|
|
|
fResult = Asn1InfoEncodeEx(
|
|
SeqOfAny_PDU,
|
|
&Asn1Info,
|
|
dwFlags,
|
|
pEncodePara,
|
|
pvEncoded,
|
|
pcbEncoded
|
|
);
|
|
|
|
goto CommonReturn;
|
|
|
|
ErrorReturn:
|
|
if (dwFlags & CRYPT_ENCODE_ALLOC_FLAG)
|
|
*((void **) pvEncoded) = NULL;
|
|
*pcbEncoded = 0;
|
|
fResult = FALSE;
|
|
CommonReturn:
|
|
Asn1X509FreeSeqOfAny(Asn1Info.value);
|
|
return fResult;
|
|
}
|
|
|
|
//+-------------------------------------------------------------------------
|
|
// SequenceOfAny Decode (ASN1 X509)
|
|
//--------------------------------------------------------------------------
|
|
BOOL WINAPI Asn1X509SequenceOfAnyDecodeExCallback(
|
|
IN void *pvAsn1Info,
|
|
IN DWORD dwFlags,
|
|
IN OPTIONAL PCRYPT_DECODE_PARA pDecodePara,
|
|
OUT OPTIONAL void *pvStructInfo,
|
|
IN OUT LONG *plRemainExtra
|
|
)
|
|
{
|
|
SeqOfAny *pAsn1Info = (SeqOfAny *) pvAsn1Info;
|
|
PCRYPT_SEQUENCE_OF_ANY pInfo = (PCRYPT_SEQUENCE_OF_ANY) pvStructInfo;
|
|
LONG lRemainExtra = *plRemainExtra;
|
|
BYTE *pbExtra;
|
|
|
|
lRemainExtra -= sizeof(CRYPT_SEQUENCE_OF_ANY);
|
|
if (lRemainExtra < 0) {
|
|
pbExtra = NULL;
|
|
} else {
|
|
pbExtra = (BYTE *) pInfo + sizeof(CRYPT_SEQUENCE_OF_ANY);
|
|
}
|
|
|
|
Asn1X509GetSeqOfAny(pAsn1Info->count, pAsn1Info->value, dwFlags,
|
|
&pInfo->cValue, &pInfo->rgValue, &pbExtra, &lRemainExtra);
|
|
|
|
*plRemainExtra = lRemainExtra;
|
|
return TRUE;
|
|
}
|
|
|
|
BOOL WINAPI Asn1X509SequenceOfAnyDecodeEx(
|
|
IN DWORD dwCertEncodingType,
|
|
IN LPCSTR lpszStructType,
|
|
IN const BYTE *pbEncoded,
|
|
IN DWORD cbEncoded,
|
|
IN DWORD dwFlags,
|
|
IN OPTIONAL PCRYPT_DECODE_PARA pDecodePara,
|
|
OUT OPTIONAL void *pvStructInfo,
|
|
IN OUT DWORD *pcbStructInfo
|
|
)
|
|
{
|
|
return Asn1InfoDecodeAndAllocEx(
|
|
SeqOfAny_PDU,
|
|
pbEncoded,
|
|
cbEncoded,
|
|
dwFlags,
|
|
pDecodePara,
|
|
Asn1X509SequenceOfAnyDecodeExCallback,
|
|
pvStructInfo,
|
|
pcbStructInfo
|
|
);
|
|
}
|
|
|
|
//+-------------------------------------------------------------------------
|
|
// UTC TIME Encode/Decode
|
|
//--------------------------------------------------------------------------
|
|
BOOL WINAPI Asn1UtcTimeEncodeEx(
|
|
IN DWORD dwCertEncodingType,
|
|
IN LPCSTR lpszStructType,
|
|
IN FILETIME * pFileTime,
|
|
IN DWORD dwFlags,
|
|
IN OPTIONAL PCRYPT_ENCODE_PARA pEncodePara,
|
|
OUT OPTIONAL void *pvEncoded,
|
|
IN OUT DWORD *pcbEncoded
|
|
) {
|
|
|
|
assert(pcbEncoded != NULL);
|
|
|
|
BOOL fResult;
|
|
UtcTime utcTime;
|
|
|
|
memset(&utcTime, 0, sizeof(UtcTime));
|
|
|
|
if( !PkiAsn1ToUTCTime(pFileTime, &utcTime) )
|
|
goto PkiAsn1ToUTCTimeError;
|
|
|
|
fResult = Asn1InfoEncodeEx(
|
|
UtcTime_PDU,
|
|
&utcTime,
|
|
dwFlags,
|
|
pEncodePara,
|
|
pvEncoded,
|
|
pcbEncoded
|
|
);
|
|
|
|
CommonReturn:
|
|
return fResult;
|
|
|
|
ErrorReturn:
|
|
if (dwFlags & CRYPT_ENCODE_ALLOC_FLAG)
|
|
*((void **) pvEncoded) = NULL;
|
|
*pcbEncoded = 0;
|
|
fResult = FALSE;
|
|
goto CommonReturn;
|
|
|
|
SET_ERROR(PkiAsn1ToUTCTimeError, CRYPT_E_BAD_ENCODE);
|
|
}
|
|
|
|
|
|
BOOL WINAPI Asn1UtcTimeDecodeExCallback(
|
|
IN void *pvAsn1Info,
|
|
IN DWORD dwFlags,
|
|
IN OPTIONAL PCRYPT_DECODE_PARA pDecodePara,
|
|
OUT OPTIONAL void *pvStructInfo,
|
|
IN OUT LONG *plRemainExtra
|
|
)
|
|
{
|
|
BOOL fResult;
|
|
UtcTime *putcTime = (UtcTime *) pvAsn1Info;
|
|
LPFILETIME pInfo = (LPFILETIME) pvStructInfo;
|
|
|
|
*plRemainExtra -= sizeof(FILETIME);
|
|
if (*plRemainExtra >= 0) {
|
|
if(!PkiAsn1FromUTCTime(putcTime, pInfo))
|
|
goto DecodeError;
|
|
}
|
|
|
|
fResult = TRUE;
|
|
CommonReturn:
|
|
return fResult;
|
|
|
|
ErrorReturn:
|
|
fResult = FALSE;
|
|
goto CommonReturn;
|
|
|
|
SET_ERROR(DecodeError, CRYPT_E_BAD_ENCODE)
|
|
}
|
|
|
|
BOOL WINAPI Asn1UtcTimeDecodeEx(
|
|
IN DWORD dwCertEncodingType,
|
|
IN LPCSTR lpszStructType,
|
|
IN const BYTE *pbEncoded,
|
|
IN DWORD cbEncoded,
|
|
IN DWORD dwFlags,
|
|
IN OPTIONAL PCRYPT_DECODE_PARA pDecodePara,
|
|
OUT OPTIONAL void *pvStructInfo,
|
|
IN OUT DWORD *pcbStructInfo
|
|
)
|
|
{
|
|
return Asn1InfoDecodeAndAllocEx(
|
|
UtcTime_PDU,
|
|
pbEncoded,
|
|
cbEncoded,
|
|
dwFlags,
|
|
pDecodePara,
|
|
Asn1UtcTimeDecodeExCallback,
|
|
pvStructInfo,
|
|
pcbStructInfo
|
|
);
|
|
}
|
|
|
|
BOOL WINAPI Asn1TimeStampRequestInfoEncodeEx(
|
|
IN DWORD dwCertEncodingType,
|
|
IN LPCSTR lpszStructType,
|
|
IN PCRYPT_TIME_STAMP_REQUEST_INFO pInfo,
|
|
IN DWORD dwFlags,
|
|
IN OPTIONAL PCRYPT_ENCODE_PARA pEncodePara,
|
|
OUT OPTIONAL void *pvEncoded,
|
|
IN OUT DWORD *pcbEncoded
|
|
)
|
|
{
|
|
BOOL fResult;
|
|
DWORD pdu;
|
|
|
|
union {
|
|
TimeStampRequest tsr;
|
|
TimeStampRequestOTS tsrocs;
|
|
} timeStampReq;
|
|
|
|
memset(&timeStampReq, 0, sizeof(TimeStampRequest));
|
|
|
|
if( !Asn1X509SetEncodedObjId(pInfo->pszTimeStampAlgorithm, &timeStampReq.tsr.timeStampAlgorithm) ||
|
|
!Asn1X509SetEncodedObjId(pInfo->pszContentType, &timeStampReq.tsr.content.contentType) )
|
|
goto Asn1X509SetEncodedObjIdError;
|
|
|
|
// only write content if it is present
|
|
if(pInfo->Content.cbData != 0)
|
|
timeStampReq.tsr.content.bit_mask |= content_present;
|
|
|
|
if(!strcmp(pInfo->pszContentType, szOID_RSA_data)) {
|
|
Asn1X509SetOctetString(&pInfo->Content, &timeStampReq.tsrocs.contentOTS.contentOTS);
|
|
pdu = TimeStampRequestOTS_PDU;
|
|
}
|
|
else {
|
|
Asn1X509SetAny(&pInfo->Content, &timeStampReq.tsr.content.content);
|
|
pdu = TimeStampRequest_PDU;
|
|
}
|
|
|
|
if (pInfo->cAttribute > 0) {
|
|
if (!Asn1X509SetAttributes(pInfo->cAttribute, pInfo->rgAttribute,
|
|
&timeStampReq.tsr.attributesTS))
|
|
goto ErrorReturn;
|
|
timeStampReq.tsr.bit_mask |= attributesTS_present;
|
|
}
|
|
|
|
fResult = Asn1InfoEncodeEx(
|
|
pdu,
|
|
&timeStampReq,
|
|
dwFlags,
|
|
pEncodePara,
|
|
pvEncoded,
|
|
pcbEncoded
|
|
);
|
|
goto CommonReturn;
|
|
|
|
CommonReturn:
|
|
Asn1X509FreeAttributes(&timeStampReq.tsr.attributesTS);
|
|
return fResult;
|
|
|
|
ErrorReturn:
|
|
if (dwFlags & CRYPT_ENCODE_ALLOC_FLAG)
|
|
*((void **) pvEncoded) = NULL;
|
|
*pcbEncoded = 0;
|
|
fResult = FALSE;
|
|
goto CommonReturn;
|
|
|
|
TRACE_ERROR(Asn1X509SetEncodedObjIdError);
|
|
}
|
|
|
|
|
|
//+-------------------------------------------------------------------------
|
|
// Decode the Time Stamp Request Info (ASN1 X509 v3 ASN.1)
|
|
//--------------------------------------------------------------------------
|
|
BOOL WINAPI Asn1TimeStampRequestInfoDecodeExCallback(
|
|
IN void *pvAsn1Info,
|
|
IN DWORD dwFlags,
|
|
IN OPTIONAL PCRYPT_DECODE_PARA pDecodePara,
|
|
OUT OPTIONAL void *pvStructInfo,
|
|
IN OUT LONG *plRemainExtra
|
|
)
|
|
{
|
|
BOOL fResult;
|
|
TimeStampRequest *pTimeStampReq = (TimeStampRequest *) pvAsn1Info;
|
|
PCRYPT_TIME_STAMP_REQUEST_INFO pInfo =
|
|
(PCRYPT_TIME_STAMP_REQUEST_INFO) pvStructInfo;
|
|
|
|
OctetStringType *pOctetStringType = NULL;
|
|
LONG lRemainExtra = *plRemainExtra;
|
|
BYTE *pbExtra;
|
|
|
|
lRemainExtra -= sizeof(CRYPT_TIME_STAMP_REQUEST_INFO);
|
|
if (lRemainExtra < 0) {
|
|
pbExtra = NULL;
|
|
} else {
|
|
// Default all optional fields to zero
|
|
memset(pInfo, 0, sizeof(CRYPT_TIME_STAMP_REQUEST_INFO));
|
|
|
|
// Update fields not needing extra memory after the CERT_INFO
|
|
pbExtra = (BYTE *) pInfo + sizeof(CRYPT_TIME_STAMP_REQUEST_INFO);
|
|
}
|
|
|
|
Asn1X509GetEncodedObjId( &pTimeStampReq->timeStampAlgorithm,
|
|
dwFlags,
|
|
&pInfo->pszTimeStampAlgorithm,
|
|
&pbExtra,
|
|
&lRemainExtra
|
|
);
|
|
Asn1X509GetEncodedObjId( &pTimeStampReq->content.contentType,
|
|
dwFlags,
|
|
&pInfo->pszContentType,
|
|
&pbExtra,
|
|
&lRemainExtra
|
|
);
|
|
|
|
if(pTimeStampReq->content.bit_mask == content_present) {
|
|
|
|
// OctetStrings will be smaller, so when doing byte counting go to
|
|
// ANY which will requre more room for decode...
|
|
if(pInfo && !strcmp(pInfo->pszContentType, szOID_RSA_data)) {
|
|
|
|
if (!Asn1InfoDecodeAndAlloc(
|
|
OctetStringType_PDU,
|
|
(const unsigned char *) pTimeStampReq->content.content.encoded,
|
|
pTimeStampReq->content.content.length,
|
|
(void **) &pOctetStringType))
|
|
goto Asn1InfoDecodeAndAllocError;
|
|
|
|
Asn1X509GetOctetString(pOctetStringType, dwFlags,
|
|
&pInfo->Content, &pbExtra, &lRemainExtra);
|
|
}
|
|
else
|
|
Asn1X509GetAny(&pTimeStampReq->content.content, dwFlags,
|
|
&pInfo->Content, &pbExtra, &lRemainExtra);
|
|
}
|
|
|
|
if (pTimeStampReq->bit_mask & attributesTS_present) {
|
|
Asn1X509GetAttributes(&pTimeStampReq->attributesTS, dwFlags,
|
|
&pInfo->cAttribute, &pInfo->rgAttribute, &pbExtra, &lRemainExtra);
|
|
}
|
|
|
|
fResult = TRUE;
|
|
|
|
CommonReturn:
|
|
Asn1InfoFree(OctetStringType_PDU, pOctetStringType);
|
|
*plRemainExtra = lRemainExtra;
|
|
return fResult;
|
|
|
|
ErrorReturn:
|
|
fResult = FALSE;
|
|
goto CommonReturn;
|
|
|
|
TRACE_ERROR(Asn1InfoDecodeAndAllocError);
|
|
}
|
|
|
|
BOOL WINAPI Asn1TimeStampRequestInfoDecodeEx(
|
|
IN DWORD dwCertEncodingType,
|
|
IN LPCSTR lpszStructType,
|
|
IN const BYTE *pbEncoded,
|
|
IN DWORD cbEncoded,
|
|
IN DWORD dwFlags,
|
|
IN OPTIONAL PCRYPT_DECODE_PARA pDecodePara,
|
|
OUT OPTIONAL void *pvStructInfo,
|
|
IN OUT DWORD *pcbStructInfo
|
|
)
|
|
{
|
|
return Asn1InfoDecodeAndAllocEx(
|
|
TimeStampRequest_PDU,
|
|
pbEncoded,
|
|
cbEncoded,
|
|
dwFlags,
|
|
pDecodePara,
|
|
Asn1TimeStampRequestInfoDecodeExCallback,
|
|
pvStructInfo,
|
|
pcbStructInfo
|
|
);
|
|
}
|
|
|
|
|
|
//+-------------------------------------------------------------------------
|
|
// Set/Free/Get CTL Usage object identifiers
|
|
//--------------------------------------------------------------------------
|
|
BOOL Asn1X509SetCtlUsage(
|
|
IN PCTL_USAGE pUsage,
|
|
OUT EnhancedKeyUsage *pAsn1
|
|
)
|
|
{
|
|
DWORD cId;
|
|
LPSTR *ppszId;
|
|
UsageIdentifier *pAsn1Id;
|
|
|
|
pAsn1->count = 0;
|
|
pAsn1->value = NULL;
|
|
cId = pUsage->cUsageIdentifier;
|
|
if (0 == cId)
|
|
return TRUE;
|
|
|
|
pAsn1Id = (UsageIdentifier *) PkiNonzeroAlloc(cId * sizeof(UsageIdentifier));
|
|
if (pAsn1Id == NULL)
|
|
return FALSE;
|
|
|
|
pAsn1->count = cId;
|
|
pAsn1->value = pAsn1Id;
|
|
ppszId = pUsage->rgpszUsageIdentifier;
|
|
for ( ; cId > 0; cId--, ppszId++, pAsn1Id++) {
|
|
if (!Asn1X509SetEncodedObjId(*ppszId, pAsn1Id))
|
|
return FALSE;
|
|
}
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
void Asn1X509FreeCtlUsage(
|
|
IN EnhancedKeyUsage *pAsn1)
|
|
{
|
|
if (pAsn1->value) {
|
|
PkiFree(pAsn1->value);
|
|
pAsn1->value = NULL;
|
|
}
|
|
}
|
|
|
|
void Asn1X509GetCtlUsage(
|
|
IN EnhancedKeyUsage *pAsn1,
|
|
IN DWORD dwFlags,
|
|
OUT PCTL_USAGE pUsage,
|
|
IN OUT BYTE **ppbExtra,
|
|
IN OUT LONG *plRemainExtra
|
|
)
|
|
{
|
|
LONG lRemainExtra = *plRemainExtra;
|
|
BYTE *pbExtra = *ppbExtra;
|
|
LONG lAlignExtra;
|
|
|
|
DWORD cId;
|
|
UsageIdentifier *pAsn1Id;
|
|
LPSTR *ppszId;
|
|
|
|
cId = pAsn1->count;
|
|
lAlignExtra = INFO_LEN_ALIGN(cId * sizeof(LPSTR));
|
|
lRemainExtra -= lAlignExtra;
|
|
if (lRemainExtra >= 0) {
|
|
pUsage->cUsageIdentifier = cId;
|
|
ppszId = (LPSTR *) pbExtra;
|
|
pUsage->rgpszUsageIdentifier = ppszId;
|
|
pbExtra += lAlignExtra;
|
|
} else
|
|
ppszId = NULL;
|
|
|
|
pAsn1Id = pAsn1->value;
|
|
for ( ; cId > 0; cId--, pAsn1Id++, ppszId++)
|
|
Asn1X509GetEncodedObjId(pAsn1Id, dwFlags, ppszId, &pbExtra, &lRemainExtra);
|
|
|
|
*plRemainExtra = lRemainExtra;
|
|
*ppbExtra = pbExtra;
|
|
}
|
|
|
|
//+-------------------------------------------------------------------------
|
|
// CTL Usage (Enhanced Key Usage) Encode (ASN1 X509)
|
|
//--------------------------------------------------------------------------
|
|
BOOL WINAPI Asn1X509CtlUsageEncodeEx(
|
|
IN DWORD dwCertEncodingType,
|
|
IN LPCSTR lpszStructType,
|
|
IN PCTL_USAGE pInfo,
|
|
IN DWORD dwFlags,
|
|
IN OPTIONAL PCRYPT_ENCODE_PARA pEncodePara,
|
|
OUT OPTIONAL void *pvEncoded,
|
|
IN OUT DWORD *pcbEncoded
|
|
)
|
|
{
|
|
BOOL fResult;
|
|
EnhancedKeyUsage Asn1Info;
|
|
|
|
if (!Asn1X509SetCtlUsage(pInfo, &Asn1Info)) {
|
|
if (dwFlags & CRYPT_ENCODE_ALLOC_FLAG)
|
|
*((void **) pvEncoded) = NULL;
|
|
*pcbEncoded = 0;
|
|
fResult = FALSE;
|
|
} else
|
|
fResult = Asn1InfoEncodeEx(
|
|
EnhancedKeyUsage_PDU,
|
|
&Asn1Info,
|
|
dwFlags,
|
|
pEncodePara,
|
|
pvEncoded,
|
|
pcbEncoded
|
|
);
|
|
Asn1X509FreeCtlUsage(&Asn1Info);
|
|
return fResult;
|
|
}
|
|
|
|
//+-------------------------------------------------------------------------
|
|
// CTL Usage (Enhanced Key Usage) Decode (ASN1 X509)
|
|
//--------------------------------------------------------------------------
|
|
BOOL WINAPI Asn1X509CtlUsageDecodeExCallback(
|
|
IN void *pvAsn1Info,
|
|
IN DWORD dwFlags,
|
|
IN OPTIONAL PCRYPT_DECODE_PARA pDecodePara,
|
|
OUT OPTIONAL void *pvStructInfo,
|
|
IN OUT LONG *plRemainExtra
|
|
)
|
|
{
|
|
EnhancedKeyUsage *pAsn1Info = (EnhancedKeyUsage *) pvAsn1Info;
|
|
PCTL_USAGE pInfo = (PCTL_USAGE) pvStructInfo;
|
|
LONG lRemainExtra = *plRemainExtra;
|
|
BYTE *pbExtra;
|
|
|
|
lRemainExtra -= sizeof(CTL_USAGE);
|
|
if (lRemainExtra < 0) {
|
|
pbExtra = NULL;
|
|
} else
|
|
pbExtra = (BYTE *) pInfo + sizeof(CTL_USAGE);
|
|
|
|
Asn1X509GetCtlUsage(pAsn1Info, dwFlags, pInfo, &pbExtra, &lRemainExtra);
|
|
|
|
*plRemainExtra = lRemainExtra;
|
|
return TRUE;
|
|
}
|
|
|
|
BOOL WINAPI Asn1X509CtlUsageDecodeEx(
|
|
IN DWORD dwCertEncodingType,
|
|
IN LPCSTR lpszStructType,
|
|
IN const BYTE *pbEncoded,
|
|
IN DWORD cbEncoded,
|
|
IN DWORD dwFlags,
|
|
IN OPTIONAL PCRYPT_DECODE_PARA pDecodePara,
|
|
OUT OPTIONAL void *pvStructInfo,
|
|
IN OUT DWORD *pcbStructInfo
|
|
)
|
|
{
|
|
return Asn1InfoDecodeAndAllocEx(
|
|
EnhancedKeyUsage_PDU,
|
|
pbEncoded,
|
|
cbEncoded,
|
|
dwFlags,
|
|
pDecodePara,
|
|
Asn1X509CtlUsageDecodeExCallback,
|
|
pvStructInfo,
|
|
pcbStructInfo
|
|
);
|
|
}
|
|
|
|
//+-------------------------------------------------------------------------
|
|
// Set/Free/Get CTL Entries
|
|
//--------------------------------------------------------------------------
|
|
BOOL Asn1X509SetCtlEntries(
|
|
IN DWORD cEntry,
|
|
IN PCTL_ENTRY pEntry,
|
|
OUT TrustedSubjects *pAsn1
|
|
)
|
|
{
|
|
TrustedSubject *pAsn1Entry;
|
|
|
|
pAsn1->value = NULL;
|
|
pAsn1->count = 0;
|
|
if (cEntry == 0)
|
|
return TRUE;
|
|
|
|
pAsn1Entry = (TrustedSubject *) PkiZeroAlloc(
|
|
cEntry * sizeof(TrustedSubject));
|
|
if (pAsn1Entry == NULL)
|
|
return FALSE;
|
|
pAsn1->value = pAsn1Entry;
|
|
pAsn1->count = cEntry;
|
|
|
|
for ( ; cEntry > 0; cEntry--, pEntry++, pAsn1Entry++) {
|
|
Asn1X509SetOctetString(&pEntry->SubjectIdentifier,
|
|
&pAsn1Entry->subjectIdentifier);
|
|
if (pEntry->cAttribute > 0) {
|
|
pAsn1Entry->bit_mask |= subjectAttributes_present;
|
|
|
|
if (!Asn1X509SetAttributes(pEntry->cAttribute, pEntry->rgAttribute,
|
|
&pAsn1Entry->subjectAttributes))
|
|
return FALSE;
|
|
}
|
|
}
|
|
return TRUE;
|
|
}
|
|
|
|
void Asn1X509FreeCtlEntries(
|
|
IN TrustedSubjects *pAsn1)
|
|
{
|
|
if (pAsn1->value) {
|
|
DWORD cEntry = pAsn1->count;
|
|
TrustedSubject *pAsn1Entry = pAsn1->value;
|
|
for ( ; cEntry > 0; cEntry--, pAsn1Entry++)
|
|
Asn1X509FreeAttributes(&pAsn1Entry->subjectAttributes);
|
|
PkiFree(pAsn1->value);
|
|
pAsn1->value = NULL;
|
|
}
|
|
pAsn1->count = 0;
|
|
}
|
|
|
|
void Asn1X509GetCtlEntries(
|
|
IN TrustedSubjects *pAsn1,
|
|
IN DWORD dwFlags,
|
|
OUT DWORD *pcEntry,
|
|
OUT PCTL_ENTRY *ppEntry,
|
|
IN OUT BYTE **ppbExtra,
|
|
IN OUT LONG *plRemainExtra
|
|
)
|
|
{
|
|
LONG lRemainExtra = *plRemainExtra;
|
|
BYTE *pbExtra = *ppbExtra;
|
|
LONG lAlignExtra;
|
|
|
|
DWORD cEntry;
|
|
TrustedSubject *pAsn1Entry;
|
|
PCTL_ENTRY pEntry;
|
|
|
|
cEntry = pAsn1->count;
|
|
lAlignExtra = INFO_LEN_ALIGN(cEntry * sizeof(CTL_ENTRY));
|
|
lRemainExtra -= lAlignExtra;
|
|
if (lRemainExtra >= 0) {
|
|
*pcEntry = cEntry;
|
|
pEntry = (PCTL_ENTRY) pbExtra;
|
|
memset(pEntry, 0, cEntry * sizeof(CTL_ENTRY));
|
|
*ppEntry = pEntry;
|
|
pbExtra += lAlignExtra;
|
|
} else
|
|
pEntry = NULL;
|
|
|
|
pAsn1Entry = pAsn1->value;
|
|
for ( ; cEntry > 0; cEntry--, pAsn1Entry++, pEntry++) {
|
|
// SubjectIdentifier
|
|
Asn1X509GetOctetString(&pAsn1Entry->subjectIdentifier, dwFlags,
|
|
&pEntry->SubjectIdentifier, &pbExtra, &lRemainExtra);
|
|
|
|
// Attributes
|
|
if (pAsn1Entry->bit_mask & subjectAttributes_present) {
|
|
Asn1X509GetAttributes(&pAsn1Entry->subjectAttributes, dwFlags,
|
|
&pEntry->cAttribute, &pEntry->rgAttribute,
|
|
&pbExtra, &lRemainExtra);
|
|
}
|
|
}
|
|
|
|
*plRemainExtra = lRemainExtra;
|
|
*ppbExtra = pbExtra;
|
|
}
|
|
|
|
//+-------------------------------------------------------------------------
|
|
// Encode the CTL Info (ASN1 X509 ASN.1)
|
|
//--------------------------------------------------------------------------
|
|
BOOL WINAPI Asn1X509CtlInfoEncodeEx(
|
|
IN DWORD dwCertEncodingType,
|
|
IN LPCSTR lpszStructType,
|
|
IN PCTL_INFO pInfo,
|
|
IN DWORD dwFlags,
|
|
IN OPTIONAL PCRYPT_ENCODE_PARA pEncodePara,
|
|
OUT OPTIONAL void *pvEncoded,
|
|
IN OUT DWORD *pcbEncoded
|
|
)
|
|
{
|
|
BOOL fResult;
|
|
CertificateTrustList Ctl;
|
|
|
|
memset(&Ctl, 0, sizeof(Ctl));
|
|
|
|
if (pInfo->dwVersion != 0) {
|
|
#ifdef OSS_CRYPT_ASN1
|
|
Ctl.CertificateTrustList_version = pInfo->dwVersion;
|
|
#else
|
|
Ctl.version = pInfo->dwVersion;
|
|
#endif // OSS_CRYPT_ASN1
|
|
Ctl.bit_mask |= CertificateTrustList_version_present;
|
|
}
|
|
if (!Asn1X509SetCtlUsage(&pInfo->SubjectUsage, &Ctl.subjectUsage))
|
|
goto ErrorReturn;
|
|
if (pInfo->ListIdentifier.cbData) {
|
|
Asn1X509SetOctetString(&pInfo->ListIdentifier, &Ctl.listIdentifier);
|
|
Ctl.bit_mask |= listIdentifier_present;
|
|
}
|
|
if (pInfo->SequenceNumber.cbData) {
|
|
if (!Asn1X509SetHugeInteger(&pInfo->SequenceNumber,
|
|
&Ctl.sequenceNumber))
|
|
goto ErrorReturn;
|
|
Ctl.bit_mask |= sequenceNumber_present;
|
|
}
|
|
if (!PkiAsn1ToChoiceOfTime(&pInfo->ThisUpdate,
|
|
&Ctl.ctlThisUpdate.choice,
|
|
&Ctl.ctlThisUpdate.u.generalTime,
|
|
&Ctl.ctlThisUpdate.u.utcTime
|
|
))
|
|
goto EncodeError;
|
|
if (pInfo->NextUpdate.dwLowDateTime || pInfo->NextUpdate.dwHighDateTime) {
|
|
Ctl.bit_mask |= ctlNextUpdate_present;
|
|
if (!PkiAsn1ToChoiceOfTime(&pInfo->NextUpdate,
|
|
&Ctl.ctlNextUpdate.choice,
|
|
&Ctl.ctlNextUpdate.u.generalTime,
|
|
&Ctl.ctlNextUpdate.u.utcTime
|
|
))
|
|
goto EncodeError;
|
|
}
|
|
if (!Asn1X509SetAlgorithm(&pInfo->SubjectAlgorithm, &Ctl.subjectAlgorithm))
|
|
goto ErrorReturn;
|
|
if (pInfo->cCTLEntry) {
|
|
if (!Asn1X509SetCtlEntries(pInfo->cCTLEntry, pInfo->rgCTLEntry,
|
|
&Ctl.trustedSubjects))
|
|
goto ErrorReturn;
|
|
Ctl.bit_mask |= trustedSubjects_present;
|
|
}
|
|
if (pInfo->cExtension) {
|
|
if (!Asn1X509SetExtensions(pInfo->cExtension, pInfo->rgExtension,
|
|
&Ctl.ctlExtensions))
|
|
goto ErrorReturn;
|
|
Ctl.bit_mask |= ctlExtensions_present;
|
|
}
|
|
|
|
fResult = Asn1InfoEncodeEx(
|
|
CertificateTrustList_PDU,
|
|
&Ctl,
|
|
dwFlags,
|
|
pEncodePara,
|
|
pvEncoded,
|
|
pcbEncoded
|
|
);
|
|
goto CommonReturn;
|
|
|
|
EncodeError:
|
|
SetLastError((DWORD) CRYPT_E_BAD_ENCODE);
|
|
ErrorReturn:
|
|
if (dwFlags & CRYPT_ENCODE_ALLOC_FLAG)
|
|
*((void **) pvEncoded) = NULL;
|
|
*pcbEncoded = 0;
|
|
fResult = FALSE;
|
|
CommonReturn:
|
|
Asn1X509FreeCtlUsage(&Ctl.subjectUsage);
|
|
Asn1X509FreeHugeInteger(&Ctl.sequenceNumber);
|
|
Asn1X509FreeCtlEntries(&Ctl.trustedSubjects);
|
|
Asn1X509FreeExtensions(&Ctl.ctlExtensions);
|
|
return fResult;
|
|
}
|
|
|
|
//+-------------------------------------------------------------------------
|
|
// Decode the CTL Info (ASN1 X509 ASN.1)
|
|
//--------------------------------------------------------------------------
|
|
BOOL WINAPI Asn1X509CtlInfoDecodeExCallback(
|
|
IN void *pvAsn1Info,
|
|
IN DWORD dwFlags,
|
|
IN OPTIONAL PCRYPT_DECODE_PARA pDecodePara,
|
|
OUT OPTIONAL void *pvStructInfo,
|
|
IN OUT LONG *plRemainExtra
|
|
)
|
|
{
|
|
BOOL fResult;
|
|
CertificateTrustList *pCtl = (CertificateTrustList *) pvAsn1Info;
|
|
PCTL_INFO pInfo = (PCTL_INFO) pvStructInfo;
|
|
LONG lRemainExtra = *plRemainExtra;
|
|
BYTE *pbExtra;
|
|
|
|
lRemainExtra -= sizeof(CTL_INFO);
|
|
if (lRemainExtra < 0) {
|
|
pbExtra = NULL;
|
|
} else {
|
|
// Default all optional fields to zero
|
|
memset(pInfo, 0, sizeof(CTL_INFO));
|
|
|
|
// Update fields not needing extra memory after the CTL_INFO
|
|
if (pCtl->bit_mask &
|
|
CertificateTrustList_version_present)
|
|
#ifdef OSS_CRYPT_ASN1
|
|
pInfo->dwVersion =
|
|
pCtl->CertificateTrustList_version;
|
|
#else
|
|
pInfo->dwVersion = pCtl->version;
|
|
#endif // OSS_CRYPT_ASN1
|
|
if (!PkiAsn1FromChoiceOfTime(pCtl->ctlThisUpdate.choice,
|
|
&pCtl->ctlThisUpdate.u.generalTime,
|
|
&pCtl->ctlThisUpdate.u.utcTime,
|
|
&pInfo->ThisUpdate))
|
|
goto DecodeError;
|
|
if (pCtl->bit_mask & ctlNextUpdate_present) {
|
|
if (!PkiAsn1FromChoiceOfTime(pCtl->ctlNextUpdate.choice,
|
|
&pCtl->ctlNextUpdate.u.generalTime,
|
|
&pCtl->ctlNextUpdate.u.utcTime,
|
|
&pInfo->NextUpdate))
|
|
goto DecodeError;
|
|
}
|
|
|
|
pbExtra = (BYTE *) pInfo + sizeof(CTL_INFO);
|
|
}
|
|
|
|
Asn1X509GetCtlUsage(&pCtl->subjectUsage, dwFlags,
|
|
&pInfo->SubjectUsage, &pbExtra, &lRemainExtra);
|
|
if (pCtl->bit_mask & listIdentifier_present)
|
|
// Always copy to force alignment
|
|
Asn1X509GetOctetString(&pCtl->listIdentifier,
|
|
dwFlags & ~CRYPT_DECODE_NOCOPY_FLAG,
|
|
&pInfo->ListIdentifier, &pbExtra, &lRemainExtra);
|
|
if (pCtl->bit_mask & sequenceNumber_present)
|
|
Asn1X509GetHugeInteger(&pCtl->sequenceNumber, dwFlags,
|
|
&pInfo->SequenceNumber, &pbExtra, &lRemainExtra);
|
|
Asn1X509GetAlgorithm(&pCtl->subjectAlgorithm, dwFlags,
|
|
&pInfo->SubjectAlgorithm, &pbExtra, &lRemainExtra);
|
|
if (pCtl->bit_mask & trustedSubjects_present)
|
|
Asn1X509GetCtlEntries(&pCtl->trustedSubjects, dwFlags,
|
|
&pInfo->cCTLEntry, &pInfo->rgCTLEntry, &pbExtra, &lRemainExtra);
|
|
if (pCtl->bit_mask & ctlExtensions_present)
|
|
Asn1X509GetExtensions(&pCtl->ctlExtensions, dwFlags,
|
|
&pInfo->cExtension, &pInfo->rgExtension, &pbExtra, &lRemainExtra);
|
|
|
|
fResult = TRUE;
|
|
CommonReturn:
|
|
*plRemainExtra = lRemainExtra;
|
|
return fResult;
|
|
|
|
ErrorReturn:
|
|
fResult = FALSE;
|
|
goto CommonReturn;
|
|
|
|
SET_ERROR(DecodeError, CRYPT_E_BAD_ENCODE)
|
|
}
|
|
|
|
BOOL WINAPI Asn1X509CtlInfoDecodeEx(
|
|
IN DWORD dwCertEncodingType,
|
|
IN LPCSTR lpszStructType,
|
|
IN const BYTE *pbEncoded,
|
|
IN DWORD cbEncoded,
|
|
IN DWORD dwFlags,
|
|
IN OPTIONAL PCRYPT_DECODE_PARA pDecodePara,
|
|
OUT OPTIONAL void *pvStructInfo,
|
|
IN OUT DWORD *pcbStructInfo
|
|
)
|
|
{
|
|
return Asn1InfoDecodeAndAllocEx(
|
|
CertificateTrustList_PDU,
|
|
pbEncoded,
|
|
cbEncoded,
|
|
dwFlags,
|
|
pDecodePara,
|
|
Asn1X509CtlInfoDecodeExCallback,
|
|
pvStructInfo,
|
|
pcbStructInfo
|
|
);
|
|
}
|
|
|
|
|
|
BOOL WINAPI Asn1X509PKIXUserNoticeEncodeEx(
|
|
IN DWORD dwCertEncodingType,
|
|
IN LPCSTR lpszStructType,
|
|
IN PCERT_POLICY_QUALIFIER_USER_NOTICE pInfo,
|
|
IN DWORD dwFlags,
|
|
IN OPTIONAL PCRYPT_ENCODE_PARA pEncodePara,
|
|
OUT OPTIONAL void *pvEncoded,
|
|
IN OUT DWORD *pcbEncoded
|
|
)
|
|
{
|
|
BOOL fResult;
|
|
UserNotice Asn1Info;
|
|
|
|
memset (&Asn1Info, 0, sizeof(Asn1Info));
|
|
|
|
if (pInfo->pNoticeReference != NULL)
|
|
{
|
|
Asn1Info.bit_mask |= noticeRef_present;
|
|
Asn1Info.noticeRef.organization = pInfo->pNoticeReference->pszOrganization;
|
|
Asn1Info.noticeRef.noticeNumbers.count = pInfo->pNoticeReference->cNoticeNumbers;
|
|
#ifdef OSS_CRYPT_ASN1
|
|
Asn1Info.noticeRef.noticeNumbers.value = pInfo->pNoticeReference->rgNoticeNumbers;
|
|
#else
|
|
Asn1Info.noticeRef.noticeNumbers.value = (ASN1int32_t *) pInfo->pNoticeReference->rgNoticeNumbers;
|
|
#endif // OSS_CRYPT_ASN1
|
|
}
|
|
|
|
if (pInfo->pszDisplayText)
|
|
{
|
|
Asn1Info.bit_mask |= explicitText_present;
|
|
Asn1Info.explicitText.choice = theBMPString_chosen;
|
|
Asn1Info.explicitText.u.theBMPString.length = wcslen(pInfo->pszDisplayText);
|
|
Asn1Info.explicitText.u.theBMPString.value = (unsigned short *) pInfo->pszDisplayText;
|
|
}
|
|
|
|
fResult = Asn1InfoEncodeEx(
|
|
UserNotice_PDU,
|
|
&Asn1Info,
|
|
dwFlags,
|
|
pEncodePara,
|
|
pvEncoded,
|
|
pcbEncoded
|
|
);
|
|
|
|
return fResult;
|
|
}
|
|
|
|
BOOL WINAPI Asn1X509PKIXUserNoticeDecodeExCallback(
|
|
IN void *pvAsn1Info,
|
|
IN DWORD dwFlags,
|
|
IN OPTIONAL PCRYPT_DECODE_PARA pDecodePara,
|
|
OUT OPTIONAL void *pvStructInfo,
|
|
IN OUT LONG *plRemainExtra
|
|
)
|
|
{
|
|
UserNotice *pAsn1UserNotice = (UserNotice *) pvAsn1Info;
|
|
PCERT_POLICY_QUALIFIER_USER_NOTICE pInfo =
|
|
(PCERT_POLICY_QUALIFIER_USER_NOTICE) pvStructInfo;
|
|
LONG lRemainExtra = *plRemainExtra;
|
|
BYTE *pbExtra;
|
|
|
|
lRemainExtra -= sizeof(CERT_POLICY_QUALIFIER_USER_NOTICE);
|
|
if (lRemainExtra < 0) {
|
|
pbExtra = NULL;
|
|
} else {
|
|
memset(pInfo, 0, sizeof(CERT_POLICY_QUALIFIER_USER_NOTICE));
|
|
pbExtra = (BYTE *) pInfo + sizeof(CERT_POLICY_QUALIFIER_USER_NOTICE);
|
|
}
|
|
|
|
// check to see if there is a notice reference
|
|
if (pAsn1UserNotice->bit_mask & noticeRef_present)
|
|
{
|
|
lRemainExtra -= sizeof(CERT_POLICY_QUALIFIER_NOTICE_REFERENCE);
|
|
if (lRemainExtra >= 0)
|
|
{
|
|
pInfo->pNoticeReference = (PCERT_POLICY_QUALIFIER_NOTICE_REFERENCE) pbExtra;
|
|
memset(pInfo->pNoticeReference, 0, sizeof(CERT_POLICY_QUALIFIER_NOTICE_REFERENCE));
|
|
pbExtra += sizeof(CERT_POLICY_QUALIFIER_NOTICE_REFERENCE);
|
|
}
|
|
|
|
lRemainExtra -= INFO_LEN_ALIGN(strlen(pAsn1UserNotice->noticeRef.organization)+1);
|
|
if (lRemainExtra >= 0)
|
|
{
|
|
pInfo->pNoticeReference->pszOrganization = (LPSTR) pbExtra;
|
|
strcpy(pInfo->pNoticeReference->pszOrganization, pAsn1UserNotice->noticeRef.organization);
|
|
pbExtra += INFO_LEN_ALIGN(strlen(pAsn1UserNotice->noticeRef.organization)+1);
|
|
}
|
|
|
|
lRemainExtra -= pAsn1UserNotice->noticeRef.noticeNumbers.count * sizeof(int);
|
|
if (lRemainExtra >= 0)
|
|
{
|
|
pInfo->pNoticeReference->cNoticeNumbers = pAsn1UserNotice->noticeRef.noticeNumbers.count;
|
|
pInfo->pNoticeReference->rgNoticeNumbers = (int *) pbExtra;
|
|
memcpy(
|
|
pInfo->pNoticeReference->rgNoticeNumbers,
|
|
pAsn1UserNotice->noticeRef.noticeNumbers.value,
|
|
pAsn1UserNotice->noticeRef.noticeNumbers.count * sizeof(int));
|
|
pbExtra += pAsn1UserNotice->noticeRef.noticeNumbers.count * sizeof(int);
|
|
}
|
|
}
|
|
else if (lRemainExtra >= 0)
|
|
{
|
|
pInfo->pNoticeReference = NULL;
|
|
}
|
|
|
|
// check to see if there is a notice reference
|
|
if (pAsn1UserNotice->bit_mask & explicitText_present)
|
|
{
|
|
// check whether it is a visible or bmp string
|
|
if (pAsn1UserNotice->explicitText.choice & theVisibleString_chosen)
|
|
{
|
|
lRemainExtra -= (strlen(pAsn1UserNotice->explicitText.u.theVisibleString)+1) * sizeof(WCHAR);
|
|
if (lRemainExtra >= 0)
|
|
{
|
|
pInfo->pszDisplayText = (LPWSTR) pbExtra;
|
|
MultiByteToWideChar(
|
|
CP_ACP,
|
|
0,
|
|
pAsn1UserNotice->explicitText.u.theVisibleString,
|
|
-1,
|
|
pInfo->pszDisplayText,
|
|
(strlen(pAsn1UserNotice->explicitText.u.theVisibleString)+1));
|
|
pbExtra += (strlen(pAsn1UserNotice->explicitText.u.theVisibleString)+1) * sizeof(WCHAR);
|
|
}
|
|
}
|
|
else if (pAsn1UserNotice->explicitText.choice & theBMPString_chosen)
|
|
{
|
|
lRemainExtra -= (pAsn1UserNotice->explicitText.u.theBMPString.length + 1) * sizeof(WCHAR);
|
|
if (lRemainExtra >= 0)
|
|
{
|
|
pInfo->pszDisplayText = (LPWSTR) pbExtra;
|
|
memcpy(
|
|
(void *)pInfo->pszDisplayText,
|
|
pAsn1UserNotice->explicitText.u.theBMPString.value,
|
|
pAsn1UserNotice->explicitText.u.theBMPString.length * sizeof(WCHAR));
|
|
pInfo->pszDisplayText[pAsn1UserNotice->explicitText.u.theBMPString.length] = 0;
|
|
pbExtra += (pAsn1UserNotice->explicitText.u.theBMPString.length + 1) * sizeof(WCHAR);
|
|
}
|
|
}
|
|
}
|
|
|
|
*plRemainExtra = lRemainExtra;
|
|
return TRUE;
|
|
}
|
|
|
|
BOOL WINAPI Asn1X509PKIXUserNoticeDecodeEx(
|
|
IN DWORD dwCertEncodingType,
|
|
IN LPCSTR lpszStructType,
|
|
IN const BYTE *pbEncoded,
|
|
IN DWORD cbEncoded,
|
|
IN DWORD dwFlags,
|
|
IN OPTIONAL PCRYPT_DECODE_PARA pDecodePara,
|
|
OUT OPTIONAL void *pvStructInfo,
|
|
IN OUT DWORD *pcbStructInfo
|
|
)
|
|
{
|
|
return Asn1InfoDecodeAndAllocEx(
|
|
UserNotice_PDU,
|
|
pbEncoded,
|
|
cbEncoded,
|
|
dwFlags,
|
|
pDecodePara,
|
|
Asn1X509PKIXUserNoticeDecodeExCallback,
|
|
pvStructInfo,
|
|
pcbStructInfo
|
|
);
|
|
}
|
|
|
|
|
|
//+-------------------------------------------------------------------------
|
|
// Encode Attributes (ASN1 X509 v3 ASN.1)
|
|
//--------------------------------------------------------------------------
|
|
BOOL WINAPI Asn1X509AttributesEncodeEx(
|
|
IN DWORD dwCertEncodingType,
|
|
IN LPCSTR lpszStructType,
|
|
IN PCRYPT_ATTRIBUTES pInfo,
|
|
IN DWORD dwFlags,
|
|
IN OPTIONAL PCRYPT_ENCODE_PARA pEncodePara,
|
|
OUT OPTIONAL void *pvEncoded,
|
|
IN OUT DWORD *pcbEncoded
|
|
)
|
|
{
|
|
BOOL fResult;
|
|
Attributes Asn1Info;
|
|
|
|
if (!Asn1X509SetAttributes(pInfo->cAttr, pInfo->rgAttr,
|
|
&Asn1Info))
|
|
goto ErrorReturn;
|
|
|
|
fResult = Asn1InfoEncodeEx(
|
|
Attributes_PDU,
|
|
&Asn1Info,
|
|
dwFlags,
|
|
pEncodePara,
|
|
pvEncoded,
|
|
pcbEncoded
|
|
);
|
|
goto CommonReturn;
|
|
|
|
ErrorReturn:
|
|
if (dwFlags & CRYPT_ENCODE_ALLOC_FLAG)
|
|
*((void **) pvEncoded) = NULL;
|
|
*pcbEncoded = 0;
|
|
fResult = FALSE;
|
|
CommonReturn:
|
|
Asn1X509FreeAttributes(&Asn1Info);
|
|
return fResult;
|
|
}
|
|
|
|
//+-------------------------------------------------------------------------
|
|
// Decode Attributes (ASN1 X509 v3 ASN.1)
|
|
//--------------------------------------------------------------------------
|
|
BOOL WINAPI Asn1X509AttributesDecodeExCallback(
|
|
IN void *pvAsn1Info,
|
|
IN DWORD dwFlags,
|
|
IN OPTIONAL PCRYPT_DECODE_PARA pDecodePara,
|
|
OUT OPTIONAL void *pvStructInfo,
|
|
IN OUT LONG *plRemainExtra
|
|
)
|
|
{
|
|
Attributes *pAsn1Info = (Attributes *) pvAsn1Info;
|
|
PCRYPT_ATTRIBUTES pInfo = (PCRYPT_ATTRIBUTES) pvStructInfo;
|
|
BYTE *pbExtra;
|
|
LONG lRemainExtra = *plRemainExtra;
|
|
|
|
lRemainExtra -= sizeof(CRYPT_ATTRIBUTES);
|
|
if (lRemainExtra < 0) {
|
|
pbExtra = NULL;
|
|
} else {
|
|
pbExtra = (BYTE *) pInfo + sizeof(CRYPT_ATTRIBUTES);
|
|
}
|
|
|
|
Asn1X509GetAttributes(pAsn1Info, dwFlags,
|
|
&pInfo->cAttr, &pInfo->rgAttr, &pbExtra, &lRemainExtra);
|
|
|
|
*plRemainExtra = lRemainExtra;
|
|
return TRUE;
|
|
}
|
|
|
|
BOOL WINAPI Asn1X509AttributesDecodeEx(
|
|
IN DWORD dwCertEncodingType,
|
|
IN LPCSTR lpszStructType,
|
|
IN const BYTE *pbEncoded,
|
|
IN DWORD cbEncoded,
|
|
IN DWORD dwFlags,
|
|
IN OPTIONAL PCRYPT_DECODE_PARA pDecodePara,
|
|
OUT OPTIONAL void *pvStructInfo,
|
|
IN OUT DWORD *pcbStructInfo
|
|
)
|
|
{
|
|
return Asn1InfoDecodeAndAllocEx(
|
|
Attributes_PDU,
|
|
pbEncoded,
|
|
cbEncoded,
|
|
dwFlags,
|
|
pDecodePara,
|
|
Asn1X509AttributesDecodeExCallback,
|
|
pvStructInfo,
|
|
pcbStructInfo
|
|
);
|
|
}
|
|
|
|
//+-------------------------------------------------------------------------
|
|
// Decode Enrollment Name Value Pair Authenticated Attributes in RA PKCS7s
|
|
//--------------------------------------------------------------------------
|
|
|
|
BOOL WINAPI Asn1NameValueDecodeExCallback(
|
|
IN void *pvAsn1Info,
|
|
IN DWORD dwFlags,
|
|
IN OPTIONAL PCRYPT_DECODE_PARA pDecodePara,
|
|
OUT OPTIONAL void *pvStructInfo,
|
|
IN OUT LONG *plRemainExtra
|
|
)
|
|
{
|
|
EnrollmentNameValuePair *pAsn1Info = (EnrollmentNameValuePair *) pvAsn1Info;
|
|
PCRYPT_ENROLLMENT_NAME_VALUE_PAIR pNameValuePair = (PCRYPT_ENROLLMENT_NAME_VALUE_PAIR) pvStructInfo;
|
|
BYTE *pbExtra;
|
|
LONG lRemainExtra = *plRemainExtra;
|
|
LONG lAlignExtra;
|
|
|
|
lRemainExtra -= sizeof(CRYPT_ENROLLMENT_NAME_VALUE_PAIR);
|
|
if (lRemainExtra < 0) {
|
|
pbExtra = NULL;
|
|
} else {
|
|
pbExtra = (BYTE *) pNameValuePair + sizeof(CRYPT_ENROLLMENT_NAME_VALUE_PAIR);
|
|
}
|
|
|
|
lAlignExtra = INFO_LEN_ALIGN(sizeof(CRYPT_ENROLLMENT_NAME_VALUE_PAIR));
|
|
lRemainExtra -= lAlignExtra;
|
|
if (lRemainExtra >= 0) {
|
|
pbExtra += lAlignExtra;
|
|
}
|
|
|
|
PkiAsn1GetBMPString(
|
|
pAsn1Info->name.length,
|
|
pAsn1Info->name.value,
|
|
0,
|
|
&pNameValuePair->pwszName,
|
|
&pbExtra,
|
|
&lRemainExtra
|
|
);
|
|
|
|
PkiAsn1GetBMPString(
|
|
pAsn1Info->value.length,
|
|
pAsn1Info->value.value,
|
|
0,
|
|
&pNameValuePair->pwszValue,
|
|
&pbExtra,
|
|
&lRemainExtra
|
|
);
|
|
|
|
*plRemainExtra = lRemainExtra;
|
|
return TRUE;
|
|
}
|
|
|
|
BOOL WINAPI Asn1NameValueDecodeEx(
|
|
IN DWORD dwCertEncodingType,
|
|
IN LPCSTR lpszStructType,
|
|
IN const BYTE *pbEncoded,
|
|
IN DWORD cbEncoded,
|
|
IN DWORD dwFlags,
|
|
IN OPTIONAL PCRYPT_DECODE_PARA pDecodePara,
|
|
OUT OPTIONAL void *pvStructInfo,
|
|
IN OUT DWORD *pcbStructInfo
|
|
)
|
|
{
|
|
return Asn1InfoDecodeAndAllocEx(
|
|
EnrollmentNameValuePair_PDU,
|
|
pbEncoded,
|
|
cbEncoded,
|
|
dwFlags,
|
|
pDecodePara,
|
|
Asn1NameValueDecodeExCallback,
|
|
pvStructInfo,
|
|
pcbStructInfo
|
|
);
|
|
}
|
|
|
|
//+-------------------------------------------------------------------------
|
|
// Encode Name Value Pair Authenticated Attributes in RA PKCS7s
|
|
//--------------------------------------------------------------------------
|
|
BOOL WINAPI Asn1NameValueEncodeEx(
|
|
IN DWORD dwCertEncodingType,
|
|
IN LPCSTR lpszStructType,
|
|
IN PCRYPT_ENROLLMENT_NAME_VALUE_PAIR pNameValue,
|
|
IN DWORD dwFlags,
|
|
IN OPTIONAL PCRYPT_ENCODE_PARA pEncodePara,
|
|
OUT OPTIONAL void *pvEncoded,
|
|
IN OUT DWORD *pcbEncoded
|
|
)
|
|
{
|
|
BOOL fResult;
|
|
EnrollmentNameValuePair NameValue;
|
|
|
|
NameValue.name.length = wcslen(pNameValue->pwszName);
|
|
NameValue.name.value = pNameValue->pwszName;
|
|
|
|
NameValue.value.length = wcslen(pNameValue->pwszValue);
|
|
NameValue.value.value = pNameValue->pwszValue;
|
|
|
|
fResult = Asn1InfoEncodeEx(
|
|
EnrollmentNameValuePair_PDU,
|
|
&NameValue,
|
|
dwFlags,
|
|
pEncodePara,
|
|
pvEncoded,
|
|
pcbEncoded
|
|
);
|
|
|
|
if (!fResult && (dwFlags & CRYPT_ENCODE_ALLOC_FLAG)) {
|
|
*((void **) pvEncoded) = NULL;
|
|
*pcbEncoded = 0;
|
|
}
|
|
|
|
return fResult;
|
|
}
|
|
|
|
//+-------------------------------------------------------------------------
|
|
// Decode CSP Provider Attribute
|
|
//--------------------------------------------------------------------------
|
|
|
|
BOOL WINAPI Asn1CSPProviderDecodeExCallback(
|
|
IN void *pvAsn1Info,
|
|
IN DWORD dwFlags,
|
|
IN OPTIONAL PCRYPT_DECODE_PARA pDecodePara,
|
|
OUT OPTIONAL void *pvStructInfo,
|
|
IN OUT LONG *plRemainExtra
|
|
)
|
|
{
|
|
CSPProvider *pAsn1Info = (CSPProvider *) pvAsn1Info;
|
|
PCRYPT_CSP_PROVIDER pCSPProvider = (PCRYPT_CSP_PROVIDER) pvStructInfo;
|
|
BYTE *pbExtra;
|
|
LONG lRemainExtra = *plRemainExtra;
|
|
LONG lAlignExtra;
|
|
|
|
lRemainExtra -= sizeof(CRYPT_CSP_PROVIDER);
|
|
if (lRemainExtra < 0) {
|
|
pbExtra = NULL;
|
|
} else {
|
|
pbExtra = (BYTE *) pCSPProvider + sizeof(CRYPT_CSP_PROVIDER);
|
|
}
|
|
|
|
lAlignExtra = INFO_LEN_ALIGN(sizeof(CRYPT_CSP_PROVIDER));
|
|
lRemainExtra -= lAlignExtra;
|
|
if (lRemainExtra >= 0) {
|
|
pbExtra += lAlignExtra;
|
|
}
|
|
|
|
pCSPProvider->dwKeySpec = (DWORD) pAsn1Info->keySpec;
|
|
|
|
PkiAsn1GetBMPString(
|
|
pAsn1Info->cspName.length,
|
|
pAsn1Info->cspName.value,
|
|
0,
|
|
&pCSPProvider->pwszProviderName,
|
|
&pbExtra,
|
|
&lRemainExtra
|
|
);
|
|
|
|
Asn1X509GetBit(
|
|
&pAsn1Info->signature,
|
|
dwFlags,
|
|
&pCSPProvider->Signature,
|
|
&pbExtra,
|
|
&lRemainExtra
|
|
);
|
|
|
|
*plRemainExtra = lRemainExtra;
|
|
return TRUE;
|
|
}
|
|
|
|
BOOL WINAPI Asn1CSPProviderDecodeEx(
|
|
IN DWORD dwCertEncodingType,
|
|
IN LPCSTR lpszStructType,
|
|
IN const BYTE *pbEncoded,
|
|
IN DWORD cbEncoded,
|
|
IN DWORD dwFlags,
|
|
IN OPTIONAL PCRYPT_DECODE_PARA pDecodePara,
|
|
OUT OPTIONAL void *pvStructInfo,
|
|
IN OUT DWORD *pcbStructInfo
|
|
)
|
|
{
|
|
return Asn1InfoDecodeAndAllocEx(
|
|
CSPProvider_PDU,
|
|
pbEncoded,
|
|
cbEncoded,
|
|
dwFlags,
|
|
pDecodePara,
|
|
Asn1CSPProviderDecodeExCallback,
|
|
pvStructInfo,
|
|
pcbStructInfo
|
|
);
|
|
}
|
|
|
|
//+-------------------------------------------------------------------------
|
|
// Encode CSP Provider Attribute
|
|
//--------------------------------------------------------------------------
|
|
BOOL WINAPI Asn1CSPProviderEncodeEx(
|
|
IN DWORD dwCertEncodingType,
|
|
IN LPCSTR lpszStructType,
|
|
IN PCRYPT_CSP_PROVIDER pCSPProvider,
|
|
IN DWORD dwFlags,
|
|
IN OPTIONAL PCRYPT_ENCODE_PARA pEncodePara,
|
|
OUT OPTIONAL void *pvEncoded,
|
|
IN OUT DWORD *pcbEncoded
|
|
)
|
|
{
|
|
BOOL fResult;
|
|
CSPProvider CspProvider;
|
|
|
|
CspProvider.keySpec = (int) pCSPProvider->dwKeySpec;
|
|
CspProvider.cspName.length = wcslen(pCSPProvider->pwszProviderName);
|
|
CspProvider.cspName.value = pCSPProvider->pwszProviderName;
|
|
|
|
Asn1X509SetBit(
|
|
&pCSPProvider->Signature,
|
|
&CspProvider.signature
|
|
);
|
|
|
|
fResult = Asn1InfoEncodeEx(
|
|
CSPProvider_PDU,
|
|
&CspProvider,
|
|
dwFlags,
|
|
pEncodePara,
|
|
pvEncoded,
|
|
pcbEncoded
|
|
);
|
|
|
|
if (!fResult && (dwFlags & CRYPT_ENCODE_ALLOC_FLAG)) {
|
|
*((void **) pvEncoded) = NULL;
|
|
*pcbEncoded = 0;
|
|
}
|
|
|
|
return fResult;
|
|
}
|
|
|
|
|
|
//+-------------------------------------------------------------------------
|
|
// Certificate Pair Encode (ASN1 X509)
|
|
//--------------------------------------------------------------------------
|
|
BOOL WINAPI Asn1X509CertPairEncodeEx(
|
|
IN DWORD dwCertEncodingType,
|
|
IN LPCSTR lpszStructType,
|
|
IN PCERT_PAIR pInfo,
|
|
IN DWORD dwFlags,
|
|
IN OPTIONAL PCRYPT_ENCODE_PARA pEncodePara,
|
|
OUT OPTIONAL void *pvEncoded,
|
|
IN OUT DWORD *pcbEncoded
|
|
)
|
|
{
|
|
CertificatePair Asn1CertificatePair;
|
|
memset(&Asn1CertificatePair, 0, sizeof(Asn1CertificatePair));
|
|
|
|
if (pInfo->Forward.cbData) {
|
|
Asn1X509SetAny(&pInfo->Forward, &Asn1CertificatePair.forward);
|
|
Asn1CertificatePair.bit_mask |= forward_present;
|
|
}
|
|
|
|
if (pInfo->Reverse.cbData) {
|
|
Asn1X509SetAny(&pInfo->Reverse, &Asn1CertificatePair.reverse);
|
|
Asn1CertificatePair.bit_mask |= reverse_present;
|
|
}
|
|
|
|
return Asn1InfoEncodeEx(
|
|
CertificatePair_PDU,
|
|
&Asn1CertificatePair,
|
|
dwFlags,
|
|
pEncodePara,
|
|
pvEncoded,
|
|
pcbEncoded
|
|
);
|
|
}
|
|
|
|
//+-------------------------------------------------------------------------
|
|
// Certificate Pair Decode (ASN1 X509)
|
|
//--------------------------------------------------------------------------
|
|
BOOL WINAPI Asn1X509CertPairDecodeExCallback(
|
|
IN void *pvAsn1Info,
|
|
IN DWORD dwFlags,
|
|
IN OPTIONAL PCRYPT_DECODE_PARA pDecodePara,
|
|
OUT OPTIONAL void *pvStructInfo,
|
|
IN OUT LONG *plRemainExtra
|
|
)
|
|
{
|
|
CertificatePair *pCertificatePair = (CertificatePair *) pvAsn1Info;
|
|
PCERT_PAIR pInfo =
|
|
(PCERT_PAIR) pvStructInfo;
|
|
LONG lRemainExtra = *plRemainExtra;
|
|
BYTE *pbExtra;
|
|
|
|
lRemainExtra -= sizeof(CERT_PAIR);
|
|
if (lRemainExtra < 0) {
|
|
pbExtra = NULL;
|
|
} else {
|
|
// Default all optional fields to zero
|
|
memset(pInfo, 0, sizeof(CERT_PAIR));
|
|
pbExtra = (BYTE *) pInfo + sizeof(CERT_PAIR);
|
|
}
|
|
|
|
if (pCertificatePair->bit_mask & forward_present)
|
|
Asn1X509GetAny(&pCertificatePair->forward, dwFlags,
|
|
&pInfo->Forward, &pbExtra, &lRemainExtra);
|
|
if (pCertificatePair->bit_mask & reverse_present)
|
|
Asn1X509GetAny(&pCertificatePair->reverse, dwFlags,
|
|
&pInfo->Reverse, &pbExtra, &lRemainExtra);
|
|
|
|
*plRemainExtra = lRemainExtra;
|
|
return TRUE;
|
|
}
|
|
|
|
BOOL WINAPI Asn1X509CertPairDecodeEx(
|
|
IN DWORD dwCertEncodingType,
|
|
IN LPCSTR lpszStructType,
|
|
IN const BYTE *pbEncoded,
|
|
IN DWORD cbEncoded,
|
|
IN DWORD dwFlags,
|
|
IN OPTIONAL PCRYPT_DECODE_PARA pDecodePara,
|
|
OUT OPTIONAL void *pvStructInfo,
|
|
IN OUT DWORD *pcbStructInfo
|
|
)
|
|
{
|
|
return Asn1InfoDecodeAndAllocEx(
|
|
CertificatePair_PDU,
|
|
pbEncoded,
|
|
cbEncoded,
|
|
dwFlags,
|
|
pDecodePara,
|
|
Asn1X509CertPairDecodeExCallback,
|
|
pvStructInfo,
|
|
pcbStructInfo
|
|
);
|
|
}
|
|
|
|
//+-------------------------------------------------------------------------
|
|
// Set/Free/Get NameConstraints Subtree
|
|
//--------------------------------------------------------------------------
|
|
BOOL Asn1X509SetNameConstraintsSubtree(
|
|
IN DWORD cSubtree,
|
|
IN PCERT_GENERAL_SUBTREE pSubtree,
|
|
IN OUT GeneralSubtrees *pAsn1,
|
|
OUT DWORD *pdwErrLocation
|
|
)
|
|
{
|
|
BOOL fResult;
|
|
DWORD i;
|
|
GeneralSubtree *pAsn1Subtree;
|
|
|
|
*pdwErrLocation = 0;
|
|
|
|
assert(0 != cSubtree);
|
|
if (NULL == (pAsn1Subtree = (GeneralSubtree *) PkiZeroAlloc(
|
|
cSubtree * sizeof(GeneralSubtree))))
|
|
goto ErrorReturn;
|
|
|
|
pAsn1->count = cSubtree;
|
|
pAsn1->value = pAsn1Subtree;
|
|
|
|
for (i = 0; i < cSubtree; i++, pSubtree++, pAsn1Subtree++) {
|
|
if (!Asn1X509SetAltNameEntry(&pSubtree->Base,
|
|
&pAsn1Subtree->base,
|
|
i,
|
|
pdwErrLocation))
|
|
goto ErrorReturn;
|
|
if (0 < pSubtree->dwMinimum) {
|
|
pAsn1Subtree->minimum = pSubtree->dwMinimum;
|
|
pAsn1Subtree->bit_mask |= minimum_present;
|
|
}
|
|
|
|
if (pSubtree->fMaximum) {
|
|
pAsn1Subtree->maximum = pSubtree->dwMaximum;
|
|
pAsn1Subtree->bit_mask |= maximum_present;
|
|
}
|
|
}
|
|
|
|
fResult = TRUE;
|
|
CommonReturn:
|
|
return fResult;
|
|
|
|
ErrorReturn:
|
|
fResult = FALSE;
|
|
goto CommonReturn;
|
|
}
|
|
|
|
void Asn1X509FreeNameConstraintsSubtree(
|
|
IN OUT GeneralSubtrees *pAsn1
|
|
)
|
|
{
|
|
DWORD cSubtree = pAsn1->count;
|
|
GeneralSubtree *pAsn1Subtree = pAsn1->value;
|
|
|
|
for ( ; cSubtree > 0; cSubtree--, pAsn1Subtree++)
|
|
Asn1X509FreeAltNameEntry(&pAsn1Subtree->base);
|
|
|
|
PkiFree(pAsn1->value);
|
|
}
|
|
|
|
BOOL Asn1X509GetNameConstraintsSubtree(
|
|
IN GeneralSubtrees *pAsn1,
|
|
IN DWORD dwFlags,
|
|
OUT DWORD *pcSubtree,
|
|
IN OUT PCERT_GENERAL_SUBTREE *ppSubtree,
|
|
IN OUT BYTE **ppbExtra,
|
|
IN OUT LONG *plRemainExtra
|
|
)
|
|
{
|
|
BOOL fResult;
|
|
BYTE *pbExtra = *ppbExtra;
|
|
LONG lRemainExtra = *plRemainExtra;
|
|
LONG lAlignExtra;
|
|
|
|
DWORD cSubtree;
|
|
GeneralSubtree *pAsn1Subtree;
|
|
PCERT_GENERAL_SUBTREE pSubtree;
|
|
|
|
cSubtree = pAsn1->count;
|
|
if (0 == cSubtree)
|
|
goto SuccessReturn;
|
|
|
|
pAsn1Subtree = pAsn1->value;
|
|
|
|
lAlignExtra = INFO_LEN_ALIGN(cSubtree * sizeof(CERT_GENERAL_SUBTREE));
|
|
lRemainExtra -= lAlignExtra;
|
|
if (lRemainExtra < 0) {
|
|
pSubtree = NULL;
|
|
} else {
|
|
pSubtree = (PCERT_GENERAL_SUBTREE) pbExtra;
|
|
memset(pSubtree, 0, lAlignExtra);
|
|
*pcSubtree = cSubtree;
|
|
*ppSubtree = pSubtree;
|
|
pbExtra += lAlignExtra;
|
|
}
|
|
|
|
// Subtree Array entries
|
|
for (; cSubtree > 0; cSubtree--, pSubtree++, pAsn1Subtree++) {
|
|
if (!Asn1X509GetAltNameEntry(&pAsn1Subtree->base, dwFlags,
|
|
&pSubtree->Base, &pbExtra, &lRemainExtra))
|
|
goto ErrorReturn;
|
|
if (lRemainExtra >= 0) {
|
|
if (pAsn1Subtree->bit_mask & minimum_present)
|
|
pSubtree->dwMinimum = pAsn1Subtree->minimum;
|
|
if (pAsn1Subtree->bit_mask & maximum_present) {
|
|
pSubtree->fMaximum = TRUE;
|
|
pSubtree->dwMaximum = pAsn1Subtree->maximum;
|
|
}
|
|
}
|
|
}
|
|
|
|
SuccessReturn:
|
|
fResult = TRUE;
|
|
CommonReturn:
|
|
*ppbExtra = pbExtra;
|
|
*plRemainExtra = lRemainExtra;
|
|
return fResult;
|
|
|
|
ErrorReturn:
|
|
fResult = FALSE;
|
|
goto CommonReturn;
|
|
}
|
|
|
|
//+-------------------------------------------------------------------------
|
|
// Name Constraints Extension Encode (ASN1 X509)
|
|
//--------------------------------------------------------------------------
|
|
BOOL WINAPI Asn1X509NameConstraintsEncodeEx(
|
|
IN DWORD dwCertEncodingType,
|
|
IN LPCSTR lpszStructType,
|
|
IN PCERT_NAME_CONSTRAINTS_INFO pInfo,
|
|
IN DWORD dwFlags,
|
|
IN OPTIONAL PCRYPT_ENCODE_PARA pEncodePara,
|
|
OUT OPTIONAL void *pvEncoded,
|
|
IN OUT DWORD *pcbEncoded
|
|
)
|
|
{
|
|
BOOL fResult;
|
|
NameConstraints Asn1Info;
|
|
DWORD cSubtree;
|
|
DWORD dwErrLocation;
|
|
|
|
if (dwFlags & CRYPT_ENCODE_ALLOC_FLAG)
|
|
*((void **) pvEncoded) = NULL;
|
|
|
|
memset(&Asn1Info, 0, sizeof(Asn1Info));
|
|
|
|
cSubtree = pInfo->cPermittedSubtree;
|
|
if (0 < cSubtree) {
|
|
if (!Asn1X509SetNameConstraintsSubtree(
|
|
cSubtree,
|
|
pInfo->rgPermittedSubtree,
|
|
&Asn1Info.permittedSubtrees,
|
|
&dwErrLocation))
|
|
goto SubtreeError;
|
|
Asn1Info.bit_mask |= permittedSubtrees_present;
|
|
}
|
|
|
|
cSubtree = pInfo->cExcludedSubtree;
|
|
if (0 < cSubtree) {
|
|
if (!Asn1X509SetNameConstraintsSubtree(
|
|
cSubtree,
|
|
pInfo->rgExcludedSubtree,
|
|
&Asn1Info.excludedSubtrees,
|
|
&dwErrLocation)) {
|
|
if (0 != dwErrLocation)
|
|
dwErrLocation |= CERT_EXCLUDED_SUBTREE_BIT;
|
|
goto SubtreeError;
|
|
}
|
|
Asn1Info.bit_mask |= excludedSubtrees_present;
|
|
}
|
|
|
|
fResult = Asn1InfoEncodeEx(
|
|
NameConstraints_PDU,
|
|
&Asn1Info,
|
|
dwFlags,
|
|
pEncodePara,
|
|
pvEncoded,
|
|
pcbEncoded
|
|
);
|
|
|
|
CommonReturn:
|
|
Asn1X509FreeNameConstraintsSubtree(&Asn1Info.permittedSubtrees);
|
|
Asn1X509FreeNameConstraintsSubtree(&Asn1Info.excludedSubtrees);
|
|
return fResult;
|
|
|
|
SubtreeError:
|
|
*pcbEncoded = dwErrLocation;
|
|
fResult = FALSE;
|
|
goto CommonReturn;
|
|
}
|
|
|
|
//+-------------------------------------------------------------------------
|
|
// Name Constraints Extension Decode (ASN1 X509)
|
|
//--------------------------------------------------------------------------
|
|
BOOL WINAPI Asn1X509NameConstraintsDecodeExCallback(
|
|
IN void *pvAsn1Info,
|
|
IN DWORD dwFlags,
|
|
IN OPTIONAL PCRYPT_DECODE_PARA pDecodePara,
|
|
OUT OPTIONAL void *pvStructInfo,
|
|
IN OUT LONG *plRemainExtra
|
|
)
|
|
{
|
|
BOOL fResult;
|
|
NameConstraints *pAsn1 = (NameConstraints *) pvAsn1Info;
|
|
PCERT_NAME_CONSTRAINTS_INFO pInfo =
|
|
(PCERT_NAME_CONSTRAINTS_INFO) pvStructInfo;
|
|
LONG lRemainExtra = *plRemainExtra;
|
|
BYTE *pbExtra;
|
|
|
|
lRemainExtra -= sizeof(CERT_NAME_CONSTRAINTS_INFO);
|
|
if (lRemainExtra < 0) {
|
|
pbExtra = NULL;
|
|
} else {
|
|
memset(pInfo, 0, sizeof(CERT_NAME_CONSTRAINTS_INFO));
|
|
pbExtra = (BYTE *) pInfo + sizeof(CERT_NAME_CONSTRAINTS_INFO);
|
|
}
|
|
|
|
if (pAsn1->bit_mask & permittedSubtrees_present) {
|
|
if (!Asn1X509GetNameConstraintsSubtree(
|
|
&pAsn1->permittedSubtrees,
|
|
dwFlags,
|
|
&pInfo->cPermittedSubtree,
|
|
&pInfo->rgPermittedSubtree,
|
|
&pbExtra,
|
|
&lRemainExtra
|
|
)) goto ErrorReturn;
|
|
}
|
|
|
|
if (pAsn1->bit_mask & excludedSubtrees_present) {
|
|
if (!Asn1X509GetNameConstraintsSubtree(
|
|
&pAsn1->excludedSubtrees,
|
|
dwFlags,
|
|
&pInfo->cExcludedSubtree,
|
|
&pInfo->rgExcludedSubtree,
|
|
&pbExtra,
|
|
&lRemainExtra
|
|
)) goto ErrorReturn;
|
|
}
|
|
|
|
fResult = TRUE;
|
|
CommonReturn:
|
|
*plRemainExtra = lRemainExtra;
|
|
return fResult;
|
|
|
|
ErrorReturn:
|
|
fResult = FALSE;
|
|
goto CommonReturn;
|
|
}
|
|
|
|
|
|
|
|
BOOL WINAPI Asn1X509NameConstraintsDecodeEx(
|
|
IN DWORD dwCertEncodingType,
|
|
IN LPCSTR lpszStructType,
|
|
IN const BYTE *pbEncoded,
|
|
IN DWORD cbEncoded,
|
|
IN DWORD dwFlags,
|
|
IN OPTIONAL PCRYPT_DECODE_PARA pDecodePara,
|
|
OUT OPTIONAL void *pvStructInfo,
|
|
IN OUT DWORD *pcbStructInfo
|
|
)
|
|
{
|
|
return Asn1InfoDecodeAndAllocEx(
|
|
NameConstraints_PDU,
|
|
pbEncoded,
|
|
cbEncoded,
|
|
dwFlags,
|
|
pDecodePara,
|
|
Asn1X509NameConstraintsDecodeExCallback,
|
|
pvStructInfo,
|
|
pcbStructInfo
|
|
);
|
|
}
|
|
|
|
//+-------------------------------------------------------------------------
|
|
// CRL Issuing Distribution Point Extension Encode (ASN1 X509)
|
|
//--------------------------------------------------------------------------
|
|
BOOL WINAPI Asn1X509CrlIssuingDistPointEncodeEx(
|
|
IN DWORD dwCertEncodingType,
|
|
IN LPCSTR lpszStructType,
|
|
IN PCRL_ISSUING_DIST_POINT pInfo,
|
|
IN DWORD dwFlags,
|
|
IN OPTIONAL PCRYPT_ENCODE_PARA pEncodePara,
|
|
OUT OPTIONAL void *pvEncoded,
|
|
IN OUT DWORD *pcbEncoded
|
|
)
|
|
{
|
|
BOOL fResult;
|
|
IssuingDistributionPoint Asn1Info;
|
|
DistributionPointName *pAsn1DistPointName;
|
|
PCRL_DIST_POINT_NAME pDistPointName;
|
|
DWORD dwErrLocation;
|
|
|
|
if (dwFlags & CRYPT_ENCODE_ALLOC_FLAG)
|
|
*((void **) pvEncoded) = NULL;
|
|
|
|
memset(&Asn1Info, 0, sizeof(Asn1Info));
|
|
|
|
pDistPointName = &pInfo->DistPointName;
|
|
if (CRL_DIST_POINT_NO_NAME !=
|
|
pDistPointName->dwDistPointNameChoice) {
|
|
pAsn1DistPointName = &Asn1Info.issuingDistributionPoint;
|
|
|
|
Asn1Info.bit_mask |= issuingDistributionPoint_present;
|
|
pAsn1DistPointName->choice = (unsigned short)
|
|
pDistPointName->dwDistPointNameChoice;
|
|
|
|
assert(fullName_chosen == CRL_DIST_POINT_FULL_NAME);
|
|
assert(nameRelativeToCRLIssuer_chosen ==
|
|
CRL_DIST_POINT_ISSUER_RDN_NAME);
|
|
|
|
switch (pDistPointName->dwDistPointNameChoice) {
|
|
case CRL_DIST_POINT_FULL_NAME:
|
|
if (!Asn1X509SetAltNames(
|
|
&pDistPointName->FullName,
|
|
&pAsn1DistPointName->u.fullName, 0, &dwErrLocation))
|
|
goto AltNamesError;
|
|
break;
|
|
case CRL_DIST_POINT_ISSUER_RDN_NAME:
|
|
default:
|
|
goto InvalidArg;
|
|
}
|
|
}
|
|
|
|
if (pInfo->fOnlyContainsUserCerts) {
|
|
Asn1Info.bit_mask |= onlyContainsUserCerts_present;
|
|
Asn1Info.onlyContainsUserCerts = TRUE;
|
|
}
|
|
if (pInfo->fOnlyContainsCACerts) {
|
|
Asn1Info.bit_mask |= onlyContainsCACerts_present;
|
|
Asn1Info.onlyContainsCACerts = TRUE;
|
|
}
|
|
if (pInfo->fIndirectCRL) {
|
|
Asn1Info.bit_mask |= indirectCRL_present;
|
|
Asn1Info.indirectCRL = TRUE;
|
|
}
|
|
|
|
if (pInfo->OnlySomeReasonFlags.cbData) {
|
|
Asn1Info.bit_mask |= onlySomeReasons_present;
|
|
Asn1X509SetBitWithoutTrailingZeroes(&pInfo->OnlySomeReasonFlags,
|
|
&Asn1Info.onlySomeReasons);
|
|
}
|
|
|
|
fResult = Asn1InfoEncodeEx(
|
|
IssuingDistributionPoint_PDU,
|
|
&Asn1Info,
|
|
dwFlags,
|
|
pEncodePara,
|
|
pvEncoded,
|
|
pcbEncoded
|
|
);
|
|
|
|
CommonReturn:
|
|
pAsn1DistPointName = &Asn1Info.issuingDistributionPoint;
|
|
switch (pAsn1DistPointName->choice) {
|
|
case CRL_DIST_POINT_FULL_NAME:
|
|
Asn1X509FreeAltNames(&pAsn1DistPointName->u.fullName);
|
|
break;
|
|
case CRL_DIST_POINT_ISSUER_RDN_NAME:
|
|
default:
|
|
break;
|
|
}
|
|
return fResult;
|
|
|
|
AltNamesError:
|
|
*pcbEncoded = dwErrLocation;
|
|
goto ErrorReturn;
|
|
|
|
InvalidArg:
|
|
SetLastError((DWORD) E_INVALIDARG);
|
|
*pcbEncoded = 0;
|
|
ErrorReturn:
|
|
fResult = FALSE;
|
|
goto CommonReturn;
|
|
}
|
|
|
|
|
|
//+-------------------------------------------------------------------------
|
|
// CRL Issuing Distribution Point Extension Decode (ASN1 X509)
|
|
//--------------------------------------------------------------------------
|
|
BOOL WINAPI Asn1X509CrlIssuingDistPointDecodeExCallback(
|
|
IN void *pvAsn1Info,
|
|
IN DWORD dwFlags,
|
|
IN OPTIONAL PCRYPT_DECODE_PARA pDecodePara,
|
|
OUT OPTIONAL void *pvStructInfo,
|
|
IN OUT LONG *plRemainExtra
|
|
)
|
|
{
|
|
BOOL fResult;
|
|
IssuingDistributionPoint *pAsn1 = (IssuingDistributionPoint *) pvAsn1Info;
|
|
PCRL_ISSUING_DIST_POINT pInfo = (PCRL_ISSUING_DIST_POINT) pvStructInfo;
|
|
LONG lRemainExtra = *plRemainExtra;
|
|
BYTE *pbExtra;
|
|
|
|
lRemainExtra -= sizeof(CRL_ISSUING_DIST_POINT);
|
|
if (lRemainExtra < 0) {
|
|
pbExtra = NULL;
|
|
} else {
|
|
memset(pInfo, 0, sizeof(CRL_ISSUING_DIST_POINT));
|
|
pbExtra = (BYTE *) pInfo + sizeof(CRL_ISSUING_DIST_POINT);
|
|
|
|
if (pAsn1->bit_mask & onlyContainsUserCerts_present)
|
|
pInfo->fOnlyContainsUserCerts =
|
|
(BOOL) pAsn1->onlyContainsUserCerts;
|
|
if (pAsn1->bit_mask & onlyContainsCACerts_present)
|
|
pInfo->fOnlyContainsCACerts = (BOOL) pAsn1->onlyContainsCACerts;
|
|
if (pAsn1->bit_mask & indirectCRL_present)
|
|
pInfo->fIndirectCRL = (BOOL) pAsn1->indirectCRL;
|
|
}
|
|
|
|
if (pAsn1->bit_mask & issuingDistributionPoint_present) {
|
|
DistributionPointName *pAsn1DistPointName =
|
|
&pAsn1->issuingDistributionPoint;
|
|
DWORD dwDistPointNameChoice = pAsn1DistPointName->choice;
|
|
PCRL_DIST_POINT_NAME pDistPointName;
|
|
|
|
if (lRemainExtra >= 0) {
|
|
pDistPointName = &pInfo->DistPointName;
|
|
pDistPointName->dwDistPointNameChoice =
|
|
dwDistPointNameChoice;
|
|
} else
|
|
pDistPointName = NULL;
|
|
|
|
assert(fullName_chosen == CRL_DIST_POINT_FULL_NAME);
|
|
assert(nameRelativeToCRLIssuer_chosen ==
|
|
CRL_DIST_POINT_ISSUER_RDN_NAME);
|
|
|
|
switch (dwDistPointNameChoice) {
|
|
case CRL_DIST_POINT_FULL_NAME:
|
|
if (!Asn1X509GetAltNames(&pAsn1DistPointName->u.fullName,
|
|
dwFlags, &pDistPointName->FullName,
|
|
&pbExtra, &lRemainExtra))
|
|
goto ErrorReturn;
|
|
break;
|
|
case CRL_DIST_POINT_ISSUER_RDN_NAME:
|
|
break;
|
|
default:
|
|
SetLastError((DWORD) CRYPT_E_BAD_ENCODE);
|
|
goto ErrorReturn;
|
|
}
|
|
}
|
|
|
|
if (pAsn1->bit_mask & onlySomeReasons_present)
|
|
Asn1X509GetBit(&pAsn1->onlySomeReasons, dwFlags,
|
|
&pInfo->OnlySomeReasonFlags, &pbExtra, &lRemainExtra);
|
|
|
|
fResult = TRUE;
|
|
CommonReturn:
|
|
*plRemainExtra = lRemainExtra;
|
|
return fResult;
|
|
|
|
ErrorReturn:
|
|
fResult = FALSE;
|
|
goto CommonReturn;
|
|
}
|
|
|
|
BOOL WINAPI Asn1X509CrlIssuingDistPointDecodeEx(
|
|
IN DWORD dwCertEncodingType,
|
|
IN LPCSTR lpszStructType,
|
|
IN const BYTE *pbEncoded,
|
|
IN DWORD cbEncoded,
|
|
IN DWORD dwFlags,
|
|
IN OPTIONAL PCRYPT_DECODE_PARA pDecodePara,
|
|
OUT OPTIONAL void *pvStructInfo,
|
|
IN OUT DWORD *pcbStructInfo
|
|
)
|
|
{
|
|
return Asn1InfoDecodeAndAllocEx(
|
|
IssuingDistributionPoint_PDU,
|
|
pbEncoded,
|
|
cbEncoded,
|
|
dwFlags,
|
|
pDecodePara,
|
|
Asn1X509CrlIssuingDistPointDecodeExCallback,
|
|
pvStructInfo,
|
|
pcbStructInfo
|
|
);
|
|
}
|
|
|
|
//+-------------------------------------------------------------------------
|
|
// Policy Mappings Extension Encode (ASN1 X509)
|
|
//--------------------------------------------------------------------------
|
|
BOOL WINAPI Asn1X509PolicyMappingsEncodeEx(
|
|
IN DWORD dwCertEncodingType,
|
|
IN LPCSTR lpszStructType,
|
|
IN PCERT_POLICY_MAPPINGS_INFO pInfo,
|
|
IN DWORD dwFlags,
|
|
IN OPTIONAL PCRYPT_ENCODE_PARA pEncodePara,
|
|
OUT OPTIONAL void *pvEncoded,
|
|
IN OUT DWORD *pcbEncoded
|
|
)
|
|
{
|
|
BOOL fResult;
|
|
PolicyMappings Asn1Info;
|
|
|
|
memset(&Asn1Info, 0, sizeof(Asn1Info));
|
|
if (0 != pInfo->cPolicyMapping) {
|
|
DWORD cMap = pInfo->cPolicyMapping;
|
|
PCERT_POLICY_MAPPING pMap = pInfo->rgPolicyMapping;
|
|
PolicyMapping *pAsn1Map;
|
|
|
|
if (NULL == (pAsn1Map = (PolicyMapping *) PkiZeroAlloc(
|
|
cMap * sizeof(PolicyMapping))))
|
|
goto ErrorReturn;
|
|
|
|
Asn1Info.count = cMap;
|
|
Asn1Info.value = pAsn1Map;
|
|
for ( ; cMap > 0; cMap--, pMap++, pAsn1Map++) {
|
|
if (!Asn1X509SetEncodedObjId(pMap->pszIssuerDomainPolicy,
|
|
&pAsn1Map->issuerDomainPolicy))
|
|
goto ErrorReturn;
|
|
if (!Asn1X509SetEncodedObjId(pMap->pszSubjectDomainPolicy,
|
|
&pAsn1Map->subjectDomainPolicy))
|
|
goto ErrorReturn;
|
|
}
|
|
}
|
|
|
|
fResult = Asn1InfoEncodeEx(
|
|
PolicyMappings_PDU,
|
|
&Asn1Info,
|
|
dwFlags,
|
|
pEncodePara,
|
|
pvEncoded,
|
|
pcbEncoded
|
|
);
|
|
|
|
goto CommonReturn;
|
|
|
|
ErrorReturn:
|
|
if (dwFlags & CRYPT_ENCODE_ALLOC_FLAG)
|
|
*((void **) pvEncoded) = NULL;
|
|
*pcbEncoded = 0;
|
|
fResult = FALSE;
|
|
CommonReturn:
|
|
PkiFree(Asn1Info.value);
|
|
return fResult;
|
|
}
|
|
|
|
//+-------------------------------------------------------------------------
|
|
// Policy Mappings Extension Decode (ASN1 X509)
|
|
//--------------------------------------------------------------------------
|
|
BOOL WINAPI Asn1X509PolicyMappingsDecodeExCallback(
|
|
IN void *pvAsn1Info,
|
|
IN DWORD dwFlags,
|
|
IN OPTIONAL PCRYPT_DECODE_PARA pDecodePara,
|
|
OUT OPTIONAL void *pvStructInfo,
|
|
IN OUT LONG *plRemainExtra
|
|
)
|
|
{
|
|
PolicyMappings *pAsn1Info = (PolicyMappings *) pvAsn1Info;
|
|
PCERT_POLICY_MAPPINGS_INFO pInfo =
|
|
(PCERT_POLICY_MAPPINGS_INFO) pvStructInfo;
|
|
LONG lRemainExtra = *plRemainExtra;
|
|
BYTE *pbExtra;
|
|
LONG lAlignExtra;
|
|
DWORD cMap;
|
|
PolicyMapping *pAsn1Map;
|
|
PCERT_POLICY_MAPPING pMap;
|
|
|
|
cMap = pAsn1Info->count;
|
|
lAlignExtra = cMap * sizeof(CERT_POLICY_MAPPING);
|
|
|
|
lRemainExtra -= sizeof(CERT_POLICY_MAPPINGS_INFO) + lAlignExtra;
|
|
if (lRemainExtra < 0) {
|
|
pbExtra = NULL;
|
|
pMap = NULL;
|
|
} else {
|
|
pbExtra = (BYTE *) pInfo + sizeof(CERT_POLICY_MAPPINGS_INFO);
|
|
pMap = (PCERT_POLICY_MAPPING) pbExtra;
|
|
pInfo->cPolicyMapping = cMap;
|
|
pInfo->rgPolicyMapping = pMap;
|
|
if (lAlignExtra) {
|
|
memset(pbExtra, 0, lAlignExtra);
|
|
pbExtra += lAlignExtra;
|
|
}
|
|
}
|
|
|
|
pAsn1Map = pAsn1Info->value;
|
|
for ( ; cMap > 0; cMap--, pAsn1Map++, pMap++) {
|
|
Asn1X509GetEncodedObjId(&pAsn1Map->issuerDomainPolicy, dwFlags,
|
|
&pMap->pszIssuerDomainPolicy, &pbExtra, &lRemainExtra);
|
|
Asn1X509GetEncodedObjId(&pAsn1Map->subjectDomainPolicy, dwFlags,
|
|
&pMap->pszSubjectDomainPolicy, &pbExtra, &lRemainExtra);
|
|
}
|
|
|
|
*plRemainExtra = lRemainExtra;
|
|
return TRUE;
|
|
}
|
|
|
|
BOOL WINAPI Asn1X509PolicyMappingsDecodeEx(
|
|
IN DWORD dwCertEncodingType,
|
|
IN LPCSTR lpszStructType,
|
|
IN const BYTE *pbEncoded,
|
|
IN DWORD cbEncoded,
|
|
IN DWORD dwFlags,
|
|
IN OPTIONAL PCRYPT_DECODE_PARA pDecodePara,
|
|
OUT OPTIONAL void *pvStructInfo,
|
|
IN OUT DWORD *pcbStructInfo
|
|
)
|
|
{
|
|
return Asn1InfoDecodeAndAllocEx(
|
|
PolicyMappings_PDU,
|
|
pbEncoded,
|
|
cbEncoded,
|
|
dwFlags,
|
|
pDecodePara,
|
|
Asn1X509PolicyMappingsDecodeExCallback,
|
|
pvStructInfo,
|
|
pcbStructInfo
|
|
);
|
|
}
|
|
|
|
//+-------------------------------------------------------------------------
|
|
// Policy Constraints Extension Encode (ASN1 X509)
|
|
//--------------------------------------------------------------------------
|
|
BOOL WINAPI Asn1X509PolicyConstraintsEncodeEx(
|
|
IN DWORD dwCertEncodingType,
|
|
IN LPCSTR lpszStructType,
|
|
IN PCERT_POLICY_CONSTRAINTS_INFO pInfo,
|
|
IN DWORD dwFlags,
|
|
IN OPTIONAL PCRYPT_ENCODE_PARA pEncodePara,
|
|
OUT OPTIONAL void *pvEncoded,
|
|
IN OUT DWORD *pcbEncoded
|
|
)
|
|
{
|
|
PolicyConstraints Asn1Info;
|
|
memset(&Asn1Info, 0, sizeof(Asn1Info));
|
|
|
|
if (pInfo->fRequireExplicitPolicy) {
|
|
Asn1Info.requireExplicitPolicy =
|
|
pInfo->dwRequireExplicitPolicySkipCerts;
|
|
Asn1Info.bit_mask |= requireExplicitPolicy_present;
|
|
}
|
|
|
|
if (pInfo->fInhibitPolicyMapping) {
|
|
Asn1Info.inhibitPolicyMapping =
|
|
pInfo->dwInhibitPolicyMappingSkipCerts;
|
|
Asn1Info.bit_mask |= inhibitPolicyMapping_present;
|
|
}
|
|
|
|
return Asn1InfoEncodeEx(
|
|
PolicyConstraints_PDU,
|
|
&Asn1Info,
|
|
dwFlags,
|
|
pEncodePara,
|
|
pvEncoded,
|
|
pcbEncoded
|
|
);
|
|
}
|
|
|
|
//+-------------------------------------------------------------------------
|
|
// Policy Constraints Extension Decode (ASN1 X509)
|
|
//--------------------------------------------------------------------------
|
|
BOOL WINAPI Asn1X509PolicyConstraintsDecodeExCallback(
|
|
IN void *pvAsn1Info,
|
|
IN DWORD dwFlags,
|
|
IN OPTIONAL PCRYPT_DECODE_PARA pDecodePara,
|
|
OUT OPTIONAL void *pvStructInfo,
|
|
IN OUT LONG *plRemainExtra
|
|
)
|
|
{
|
|
PolicyConstraints *pAsn1Info = (PolicyConstraints *) pvAsn1Info;
|
|
PCERT_POLICY_CONSTRAINTS_INFO pInfo =
|
|
(PCERT_POLICY_CONSTRAINTS_INFO) pvStructInfo;
|
|
|
|
*plRemainExtra -= sizeof(CERT_POLICY_CONSTRAINTS_INFO);
|
|
if (*plRemainExtra >= 0) {
|
|
memset(pInfo, 0, sizeof(CERT_POLICY_CONSTRAINTS_INFO));
|
|
|
|
if (pAsn1Info->bit_mask & requireExplicitPolicy_present) {
|
|
pInfo->fRequireExplicitPolicy = TRUE;
|
|
pInfo->dwRequireExplicitPolicySkipCerts =
|
|
pAsn1Info->requireExplicitPolicy;
|
|
}
|
|
|
|
if (pAsn1Info->bit_mask & inhibitPolicyMapping_present) {
|
|
pInfo->fInhibitPolicyMapping = TRUE;
|
|
pInfo->dwInhibitPolicyMappingSkipCerts =
|
|
pAsn1Info->inhibitPolicyMapping;
|
|
}
|
|
}
|
|
return TRUE;
|
|
}
|
|
|
|
BOOL WINAPI Asn1X509PolicyConstraintsDecodeEx(
|
|
IN DWORD dwCertEncodingType,
|
|
IN LPCSTR lpszStructType,
|
|
IN const BYTE *pbEncoded,
|
|
IN DWORD cbEncoded,
|
|
IN DWORD dwFlags,
|
|
IN OPTIONAL PCRYPT_DECODE_PARA pDecodePara,
|
|
OUT OPTIONAL void *pvStructInfo,
|
|
IN OUT DWORD *pcbStructInfo
|
|
)
|
|
{
|
|
return Asn1InfoDecodeAndAllocEx(
|
|
PolicyConstraints_PDU,
|
|
pbEncoded,
|
|
cbEncoded,
|
|
dwFlags,
|
|
pDecodePara,
|
|
Asn1X509PolicyConstraintsDecodeExCallback,
|
|
pvStructInfo,
|
|
pcbStructInfo
|
|
);
|
|
}
|
|
|
|
//+-------------------------------------------------------------------------
|
|
// Cross Cert Distribution Points Encode (ASN1 X509)
|
|
//--------------------------------------------------------------------------
|
|
BOOL WINAPI Asn1X509CrossCertDistPointsEncodeEx(
|
|
IN DWORD dwCertEncodingType,
|
|
IN LPCSTR lpszStructType,
|
|
IN PCROSS_CERT_DIST_POINTS_INFO pInfo,
|
|
IN DWORD dwFlags,
|
|
IN OPTIONAL PCRYPT_ENCODE_PARA pEncodePara,
|
|
OUT OPTIONAL void *pvEncoded,
|
|
IN OUT DWORD *pcbEncoded
|
|
)
|
|
{
|
|
BOOL fResult;
|
|
CrossCertDistPoints Asn1Info;
|
|
GeneralNames *pAsn1DistPoint;
|
|
PCERT_ALT_NAME_INFO pDistPoint;
|
|
DWORD cDistPoint;
|
|
DWORD i;
|
|
DWORD dwErrLocation;
|
|
|
|
if (dwFlags & CRYPT_ENCODE_ALLOC_FLAG)
|
|
*((void **) pvEncoded) = NULL;
|
|
|
|
memset(&Asn1Info, 0, sizeof(Asn1Info));
|
|
if (pInfo->dwSyncDeltaTime) {
|
|
Asn1Info.syncDeltaTime = pInfo->dwSyncDeltaTime;
|
|
Asn1Info.bit_mask |= syncDeltaTime_present;
|
|
}
|
|
|
|
cDistPoint = pInfo->cDistPoint;
|
|
if (0 < cDistPoint) {
|
|
if (NULL == (pAsn1DistPoint = (GeneralNames *) PkiZeroAlloc(
|
|
cDistPoint * sizeof(GeneralNames))))
|
|
goto ErrorReturn;
|
|
Asn1Info.crossCertDistPointNames.count = cDistPoint;
|
|
Asn1Info.crossCertDistPointNames.value = pAsn1DistPoint;
|
|
|
|
pDistPoint = pInfo->rgDistPoint;
|
|
for (i = 0; i < cDistPoint; i++, pDistPoint++, pAsn1DistPoint++) {
|
|
if (!Asn1X509SetAltNames(
|
|
pDistPoint,
|
|
pAsn1DistPoint,
|
|
i,
|
|
&dwErrLocation))
|
|
goto AltNamesError;
|
|
}
|
|
}
|
|
|
|
fResult = Asn1InfoEncodeEx(
|
|
CrossCertDistPoints_PDU,
|
|
&Asn1Info,
|
|
dwFlags,
|
|
pEncodePara,
|
|
pvEncoded,
|
|
pcbEncoded
|
|
);
|
|
|
|
CommonReturn:
|
|
pAsn1DistPoint = Asn1Info.crossCertDistPointNames.value;
|
|
if (pAsn1DistPoint) {
|
|
cDistPoint = Asn1Info.crossCertDistPointNames.count;
|
|
for ( ; cDistPoint > 0; cDistPoint--, pAsn1DistPoint++) {
|
|
Asn1X509FreeAltNames(pAsn1DistPoint);
|
|
}
|
|
PkiFree(Asn1Info.crossCertDistPointNames.value);
|
|
}
|
|
return fResult;
|
|
|
|
AltNamesError:
|
|
*pcbEncoded = dwErrLocation;
|
|
fResult = FALSE;
|
|
goto CommonReturn;
|
|
|
|
ErrorReturn:
|
|
*pcbEncoded = 0;
|
|
fResult = FALSE;
|
|
goto CommonReturn;
|
|
}
|
|
|
|
//+-------------------------------------------------------------------------
|
|
// Cross Cert Distribution Points Decode (ASN1 X509)
|
|
//--------------------------------------------------------------------------
|
|
BOOL WINAPI Asn1X509CrossCertDistPointsDecodeExCallback(
|
|
IN void *pvAsn1Info,
|
|
IN DWORD dwFlags,
|
|
IN OPTIONAL PCRYPT_DECODE_PARA pDecodePara,
|
|
OUT OPTIONAL void *pvStructInfo,
|
|
IN OUT LONG *plRemainExtra
|
|
)
|
|
{
|
|
BOOL fResult;
|
|
CrossCertDistPoints *pAsn1 = (CrossCertDistPoints *) pvAsn1Info;
|
|
PCROSS_CERT_DIST_POINTS_INFO pInfo =
|
|
(PCROSS_CERT_DIST_POINTS_INFO) pvStructInfo;
|
|
LONG lRemainExtra = *plRemainExtra;
|
|
BYTE *pbExtra;
|
|
LONG lAlignExtra;
|
|
|
|
lRemainExtra -= sizeof(CROSS_CERT_DIST_POINTS_INFO);
|
|
if (lRemainExtra < 0) {
|
|
pbExtra = NULL;
|
|
} else {
|
|
memset(pInfo, 0, sizeof(CROSS_CERT_DIST_POINTS_INFO));
|
|
pbExtra = (BYTE *) pInfo + sizeof(CROSS_CERT_DIST_POINTS_INFO);
|
|
|
|
if (pAsn1->bit_mask & syncDeltaTime_present)
|
|
pInfo->dwSyncDeltaTime = pAsn1->syncDeltaTime;
|
|
}
|
|
|
|
if (pAsn1->crossCertDistPointNames.count) {
|
|
DWORD cDistPoint = pAsn1->crossCertDistPointNames.count;
|
|
GeneralNames *pAsn1DistPoint = pAsn1->crossCertDistPointNames.value;
|
|
PCERT_ALT_NAME_INFO pDistPoint;
|
|
|
|
lAlignExtra = INFO_LEN_ALIGN(cDistPoint * sizeof(CERT_ALT_NAME_INFO));
|
|
lRemainExtra -= lAlignExtra;
|
|
if (lRemainExtra >= 0) {
|
|
pDistPoint = (PCERT_ALT_NAME_INFO) pbExtra;
|
|
memset(pDistPoint, 0, cDistPoint * sizeof(CERT_ALT_NAME_INFO));
|
|
pInfo->cDistPoint = cDistPoint;
|
|
pInfo->rgDistPoint = pDistPoint;
|
|
pbExtra += lAlignExtra;
|
|
} else
|
|
pDistPoint = NULL;
|
|
|
|
for ( ; cDistPoint > 0; cDistPoint--, pAsn1DistPoint++, pDistPoint++) {
|
|
if (!Asn1X509GetAltNames(pAsn1DistPoint, dwFlags, pDistPoint,
|
|
&pbExtra, &lRemainExtra))
|
|
goto ErrorReturn;
|
|
}
|
|
}
|
|
|
|
fResult = TRUE;
|
|
CommonReturn:
|
|
*plRemainExtra = lRemainExtra;
|
|
return fResult;
|
|
|
|
ErrorReturn:
|
|
fResult = FALSE;
|
|
goto CommonReturn;
|
|
}
|
|
|
|
BOOL WINAPI Asn1X509CrossCertDistPointsDecodeEx(
|
|
IN DWORD dwCertEncodingType,
|
|
IN LPCSTR lpszStructType,
|
|
IN const BYTE *pbEncoded,
|
|
IN DWORD cbEncoded,
|
|
IN DWORD dwFlags,
|
|
IN OPTIONAL PCRYPT_DECODE_PARA pDecodePara,
|
|
OUT OPTIONAL void *pvStructInfo,
|
|
IN OUT DWORD *pcbStructInfo
|
|
)
|
|
{
|
|
return Asn1InfoDecodeAndAllocEx(
|
|
CrossCertDistPoints_PDU,
|
|
pbEncoded,
|
|
cbEncoded,
|
|
dwFlags,
|
|
pDecodePara,
|
|
Asn1X509CrossCertDistPointsDecodeExCallback,
|
|
pvStructInfo,
|
|
pcbStructInfo
|
|
);
|
|
}
|
|
|
|
//+=========================================================================
|
|
// Certificate Management Messages over CMS (CMC) Encode/Decode Functions
|
|
//==========================================================================
|
|
|
|
//+-------------------------------------------------------------------------
|
|
// Set/Free/Get CMC Tagged Attributes
|
|
//--------------------------------------------------------------------------
|
|
BOOL Asn1CmcSetTaggedAttributes(
|
|
IN DWORD cTaggedAttr,
|
|
IN PCMC_TAGGED_ATTRIBUTE pTaggedAttr,
|
|
OUT ControlSequence *pAsn1
|
|
)
|
|
{
|
|
TaggedAttribute *pAsn1Attr;
|
|
|
|
pAsn1->value = NULL;
|
|
pAsn1->count = 0;
|
|
if (cTaggedAttr == 0)
|
|
return TRUE;
|
|
|
|
pAsn1Attr = (TaggedAttribute *) PkiZeroAlloc(
|
|
cTaggedAttr * sizeof(TaggedAttribute));
|
|
if (pAsn1Attr == NULL)
|
|
return FALSE;
|
|
pAsn1->value = pAsn1Attr;
|
|
pAsn1->count = cTaggedAttr;
|
|
|
|
for ( ; cTaggedAttr > 0; cTaggedAttr--, pTaggedAttr++, pAsn1Attr++) {
|
|
pAsn1Attr->bodyPartID = pTaggedAttr->dwBodyPartID;
|
|
if (!Asn1X509SetEncodedObjId(pTaggedAttr->Attribute.pszObjId,
|
|
&pAsn1Attr->type))
|
|
return FALSE;
|
|
|
|
if (!Asn1X509SetSeqOfAny(
|
|
pTaggedAttr->Attribute.cValue,
|
|
pTaggedAttr->Attribute.rgValue,
|
|
&pAsn1Attr->values.count,
|
|
&pAsn1Attr->values.value))
|
|
return FALSE;
|
|
}
|
|
return TRUE;
|
|
}
|
|
|
|
void Asn1CmcFreeTaggedAttributes(
|
|
IN OUT ControlSequence *pAsn1
|
|
)
|
|
{
|
|
if (pAsn1->value) {
|
|
TaggedAttribute *pAsn1Attr = pAsn1->value;
|
|
DWORD cTaggedAttr = pAsn1->count;
|
|
|
|
for ( ; cTaggedAttr > 0; cTaggedAttr--, pAsn1Attr++) {
|
|
Asn1X509FreeSeqOfAny(pAsn1Attr->values.value);
|
|
}
|
|
PkiFree(pAsn1->value);
|
|
pAsn1->value = NULL;
|
|
}
|
|
pAsn1->count = 0;
|
|
}
|
|
|
|
void Asn1CmcGetTaggedAttributes(
|
|
IN ControlSequence *pAsn1,
|
|
IN DWORD dwFlags,
|
|
OUT DWORD *pcTaggedAttr,
|
|
OUT PCMC_TAGGED_ATTRIBUTE *ppTaggedAttr,
|
|
IN OUT BYTE **ppbExtra,
|
|
IN OUT LONG *plRemainExtra
|
|
)
|
|
{
|
|
LONG lRemainExtra = *plRemainExtra;
|
|
BYTE *pbExtra = *ppbExtra;
|
|
LONG lAlignExtra;
|
|
|
|
DWORD cTaggedAttr;
|
|
TaggedAttribute *pAsn1Attr;
|
|
PCMC_TAGGED_ATTRIBUTE pTaggedAttr;
|
|
|
|
cTaggedAttr = pAsn1->count;
|
|
lAlignExtra = INFO_LEN_ALIGN(cTaggedAttr * sizeof(CMC_TAGGED_ATTRIBUTE));
|
|
lRemainExtra -= lAlignExtra;
|
|
if (lRemainExtra >= 0) {
|
|
*pcTaggedAttr = cTaggedAttr;
|
|
pTaggedAttr = (PCMC_TAGGED_ATTRIBUTE) pbExtra;
|
|
*ppTaggedAttr = pTaggedAttr;
|
|
pbExtra += lAlignExtra;
|
|
} else
|
|
pTaggedAttr = NULL;
|
|
|
|
pAsn1Attr = pAsn1->value;
|
|
for ( ; cTaggedAttr > 0; cTaggedAttr--, pAsn1Attr++, pTaggedAttr++) {
|
|
if (lRemainExtra >= 0) {
|
|
pTaggedAttr->dwBodyPartID = pAsn1Attr->bodyPartID;
|
|
}
|
|
Asn1X509GetEncodedObjId(&pAsn1Attr->type, dwFlags,
|
|
&pTaggedAttr->Attribute.pszObjId, &pbExtra, &lRemainExtra);
|
|
Asn1X509GetSeqOfAny(
|
|
pAsn1Attr->values.count, pAsn1Attr->values.value, dwFlags,
|
|
&pTaggedAttr->Attribute.cValue, &pTaggedAttr->Attribute.rgValue,
|
|
&pbExtra, &lRemainExtra);
|
|
}
|
|
|
|
*plRemainExtra = lRemainExtra;
|
|
*ppbExtra = pbExtra;
|
|
}
|
|
|
|
//+-------------------------------------------------------------------------
|
|
// Set/Free/Get CMC Tagged Requests
|
|
//--------------------------------------------------------------------------
|
|
BOOL Asn1CmcSetTaggedRequests(
|
|
IN DWORD cTaggedReq,
|
|
IN PCMC_TAGGED_REQUEST pTaggedReq,
|
|
OUT ReqSequence *pAsn1
|
|
)
|
|
{
|
|
TaggedRequest *pAsn1Req;
|
|
|
|
pAsn1->value = NULL;
|
|
pAsn1->count = 0;
|
|
if (cTaggedReq == 0)
|
|
return TRUE;
|
|
|
|
pAsn1Req = (TaggedRequest *) PkiZeroAlloc(
|
|
cTaggedReq * sizeof(TaggedRequest));
|
|
if (pAsn1Req == NULL)
|
|
return FALSE;
|
|
pAsn1->value = pAsn1Req;
|
|
pAsn1->count = cTaggedReq;
|
|
|
|
for ( ; cTaggedReq > 0; cTaggedReq--, pTaggedReq++, pAsn1Req++) {
|
|
PCMC_TAGGED_CERT_REQUEST pTaggedCertReq;
|
|
TaggedCertificationRequest *ptcr;
|
|
|
|
if (CMC_TAGGED_CERT_REQUEST_CHOICE !=
|
|
pTaggedReq->dwTaggedRequestChoice) {
|
|
SetLastError((DWORD) E_INVALIDARG);
|
|
return FALSE;
|
|
}
|
|
|
|
pAsn1Req->choice = tcr_chosen;
|
|
ptcr = &pAsn1Req->u.tcr;
|
|
pTaggedCertReq = pTaggedReq->pTaggedCertRequest;
|
|
|
|
ptcr->bodyPartID = pTaggedCertReq->dwBodyPartID;
|
|
Asn1X509SetAny(&pTaggedCertReq->SignedCertRequest,
|
|
&ptcr->certificationRequest);
|
|
}
|
|
return TRUE;
|
|
}
|
|
|
|
void Asn1CmcFreeTaggedRequests(
|
|
IN OUT ReqSequence *pAsn1
|
|
)
|
|
{
|
|
if (pAsn1->value) {
|
|
PkiFree(pAsn1->value);
|
|
pAsn1->value = NULL;
|
|
}
|
|
pAsn1->count = 0;
|
|
}
|
|
|
|
BOOL Asn1CmcGetTaggedRequests(
|
|
IN ReqSequence *pAsn1,
|
|
IN DWORD dwFlags,
|
|
OUT DWORD *pcTaggedReq,
|
|
OUT PCMC_TAGGED_REQUEST *ppTaggedReq,
|
|
IN OUT BYTE **ppbExtra,
|
|
IN OUT LONG *plRemainExtra
|
|
)
|
|
{
|
|
BOOL fResult;
|
|
LONG lRemainExtra = *plRemainExtra;
|
|
BYTE *pbExtra = *ppbExtra;
|
|
LONG lAlignExtra;
|
|
|
|
DWORD cTaggedReq;
|
|
TaggedRequest *pAsn1Req;
|
|
PCMC_TAGGED_REQUEST pTaggedReq;
|
|
|
|
cTaggedReq = pAsn1->count;
|
|
lAlignExtra = INFO_LEN_ALIGN(cTaggedReq * sizeof(CMC_TAGGED_REQUEST));
|
|
lRemainExtra -= lAlignExtra;
|
|
if (lRemainExtra >= 0) {
|
|
*pcTaggedReq = cTaggedReq;
|
|
pTaggedReq = (PCMC_TAGGED_REQUEST) pbExtra;
|
|
*ppTaggedReq = pTaggedReq;
|
|
pbExtra += lAlignExtra;
|
|
} else
|
|
pTaggedReq = NULL;
|
|
|
|
pAsn1Req = pAsn1->value;
|
|
for ( ; cTaggedReq > 0; cTaggedReq--, pAsn1Req++, pTaggedReq++) {
|
|
PCMC_TAGGED_CERT_REQUEST pTaggedCertReq;
|
|
TaggedCertificationRequest *ptcr;
|
|
|
|
if (tcr_chosen != pAsn1Req->choice) {
|
|
SetLastError((DWORD) CRYPT_E_BAD_ENCODE);
|
|
goto ErrorReturn;
|
|
}
|
|
|
|
ptcr = &pAsn1Req->u.tcr;
|
|
|
|
lAlignExtra = INFO_LEN_ALIGN(sizeof(CMC_TAGGED_CERT_REQUEST));
|
|
lRemainExtra -= lAlignExtra;
|
|
if (lRemainExtra >= 0) {
|
|
pTaggedReq->dwTaggedRequestChoice =
|
|
CMC_TAGGED_CERT_REQUEST_CHOICE;
|
|
|
|
pTaggedCertReq = (PCMC_TAGGED_CERT_REQUEST) pbExtra;
|
|
pbExtra += lAlignExtra;
|
|
|
|
pTaggedReq->pTaggedCertRequest = pTaggedCertReq;
|
|
pTaggedCertReq->dwBodyPartID = ptcr->bodyPartID;
|
|
} else
|
|
pTaggedCertReq = NULL;
|
|
|
|
Asn1X509GetAny(&ptcr->certificationRequest, dwFlags,
|
|
&pTaggedCertReq->SignedCertRequest, &pbExtra, &lRemainExtra);
|
|
}
|
|
|
|
*plRemainExtra = lRemainExtra;
|
|
*ppbExtra = pbExtra;
|
|
|
|
fResult = TRUE;
|
|
CommonReturn:
|
|
return fResult;
|
|
|
|
ErrorReturn:
|
|
fResult = FALSE;
|
|
goto CommonReturn;
|
|
}
|
|
|
|
//+-------------------------------------------------------------------------
|
|
// Set/Free/Get CMC Tagged ContentInfo
|
|
//--------------------------------------------------------------------------
|
|
BOOL Asn1CmcSetTaggedContentInfos(
|
|
IN DWORD cTaggedCI,
|
|
IN PCMC_TAGGED_CONTENT_INFO pTaggedCI,
|
|
OUT CmsSequence *pAsn1
|
|
)
|
|
{
|
|
TaggedContentInfo *pAsn1CI;
|
|
|
|
pAsn1->value = NULL;
|
|
pAsn1->count = 0;
|
|
if (cTaggedCI == 0)
|
|
return TRUE;
|
|
|
|
pAsn1CI = (TaggedContentInfo *) PkiZeroAlloc(
|
|
cTaggedCI * sizeof(TaggedContentInfo));
|
|
if (pAsn1CI == NULL)
|
|
return FALSE;
|
|
pAsn1->value = pAsn1CI;
|
|
pAsn1->count = cTaggedCI;
|
|
|
|
for ( ; cTaggedCI > 0; cTaggedCI--, pTaggedCI++, pAsn1CI++) {
|
|
pAsn1CI->bodyPartID = pTaggedCI->dwBodyPartID;
|
|
Asn1X509SetAny(&pTaggedCI->EncodedContentInfo, &pAsn1CI->contentInfo);
|
|
}
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
void Asn1CmcFreeTaggedContentInfos(
|
|
IN OUT CmsSequence *pAsn1
|
|
)
|
|
{
|
|
if (pAsn1->value) {
|
|
PkiFree(pAsn1->value);
|
|
pAsn1->value = NULL;
|
|
}
|
|
pAsn1->count = 0;
|
|
}
|
|
|
|
void Asn1CmcGetTaggedContentInfos(
|
|
IN CmsSequence *pAsn1,
|
|
IN DWORD dwFlags,
|
|
OUT DWORD *pcTaggedCI,
|
|
OUT PCMC_TAGGED_CONTENT_INFO *ppTaggedCI,
|
|
IN OUT BYTE **ppbExtra,
|
|
IN OUT LONG *plRemainExtra
|
|
)
|
|
{
|
|
LONG lRemainExtra = *plRemainExtra;
|
|
BYTE *pbExtra = *ppbExtra;
|
|
LONG lAlignExtra;
|
|
|
|
DWORD cTaggedCI;
|
|
TaggedContentInfo *pAsn1CI;
|
|
PCMC_TAGGED_CONTENT_INFO pTaggedCI;
|
|
|
|
cTaggedCI = pAsn1->count;
|
|
lAlignExtra = INFO_LEN_ALIGN(cTaggedCI * sizeof(CMC_TAGGED_CONTENT_INFO));
|
|
lRemainExtra -= lAlignExtra;
|
|
if (lRemainExtra >= 0) {
|
|
*pcTaggedCI = cTaggedCI;
|
|
pTaggedCI = (PCMC_TAGGED_CONTENT_INFO) pbExtra;
|
|
*ppTaggedCI = pTaggedCI;
|
|
pbExtra += lAlignExtra;
|
|
} else
|
|
pTaggedCI = NULL;
|
|
|
|
pAsn1CI = pAsn1->value;
|
|
for ( ; cTaggedCI > 0; cTaggedCI--, pAsn1CI++, pTaggedCI++) {
|
|
if (lRemainExtra >= 0) {
|
|
pTaggedCI->dwBodyPartID = pAsn1CI->bodyPartID;
|
|
}
|
|
|
|
Asn1X509GetAny(&pAsn1CI->contentInfo, dwFlags,
|
|
&pTaggedCI->EncodedContentInfo, &pbExtra, &lRemainExtra);
|
|
}
|
|
|
|
*plRemainExtra = lRemainExtra;
|
|
*ppbExtra = pbExtra;
|
|
}
|
|
|
|
//+-------------------------------------------------------------------------
|
|
// Set/Free/Get CMC Tagged OtherMsg
|
|
//--------------------------------------------------------------------------
|
|
BOOL Asn1CmcSetTaggedOtherMsgs(
|
|
IN DWORD cTaggedOM,
|
|
IN PCMC_TAGGED_OTHER_MSG pTaggedOM,
|
|
OUT OtherMsgSequence *pAsn1
|
|
)
|
|
{
|
|
TaggedOtherMsg *pAsn1OM;
|
|
|
|
pAsn1->value = NULL;
|
|
pAsn1->count = 0;
|
|
if (cTaggedOM == 0)
|
|
return TRUE;
|
|
|
|
pAsn1OM = (TaggedOtherMsg *) PkiZeroAlloc(
|
|
cTaggedOM * sizeof(TaggedOtherMsg));
|
|
if (pAsn1OM == NULL)
|
|
return FALSE;
|
|
pAsn1->value = pAsn1OM;
|
|
pAsn1->count = cTaggedOM;
|
|
|
|
for ( ; cTaggedOM > 0; cTaggedOM--, pTaggedOM++, pAsn1OM++) {
|
|
pAsn1OM->bodyPartID = pTaggedOM->dwBodyPartID;
|
|
|
|
if (!Asn1X509SetEncodedObjId(pTaggedOM->pszObjId,
|
|
&pAsn1OM->otherMsgType))
|
|
return FALSE;
|
|
|
|
Asn1X509SetAny(&pTaggedOM->Value, &pAsn1OM->otherMsgValue);
|
|
}
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
void Asn1CmcFreeTaggedOtherMsgs(
|
|
IN OUT OtherMsgSequence *pAsn1
|
|
)
|
|
{
|
|
if (pAsn1->value) {
|
|
PkiFree(pAsn1->value);
|
|
pAsn1->value = NULL;
|
|
}
|
|
pAsn1->count = 0;
|
|
}
|
|
|
|
void Asn1CmcGetTaggedOtherMsgs(
|
|
IN OtherMsgSequence *pAsn1,
|
|
IN DWORD dwFlags,
|
|
OUT DWORD *pcTaggedOM,
|
|
OUT PCMC_TAGGED_OTHER_MSG *ppTaggedOM,
|
|
IN OUT BYTE **ppbExtra,
|
|
IN OUT LONG *plRemainExtra
|
|
)
|
|
{
|
|
LONG lRemainExtra = *plRemainExtra;
|
|
BYTE *pbExtra = *ppbExtra;
|
|
LONG lAlignExtra;
|
|
|
|
DWORD cTaggedOM;
|
|
TaggedOtherMsg *pAsn1OM;
|
|
PCMC_TAGGED_OTHER_MSG pTaggedOM;
|
|
|
|
cTaggedOM = pAsn1->count;
|
|
lAlignExtra = INFO_LEN_ALIGN(cTaggedOM * sizeof(CMC_TAGGED_OTHER_MSG));
|
|
lRemainExtra -= lAlignExtra;
|
|
if (lRemainExtra >= 0) {
|
|
*pcTaggedOM = cTaggedOM;
|
|
pTaggedOM = (PCMC_TAGGED_OTHER_MSG) pbExtra;
|
|
*ppTaggedOM = pTaggedOM;
|
|
pbExtra += lAlignExtra;
|
|
} else
|
|
pTaggedOM = NULL;
|
|
|
|
pAsn1OM = pAsn1->value;
|
|
for ( ; cTaggedOM > 0; cTaggedOM--, pAsn1OM++, pTaggedOM++) {
|
|
if (lRemainExtra >= 0) {
|
|
pTaggedOM->dwBodyPartID = pAsn1OM->bodyPartID;
|
|
}
|
|
|
|
Asn1X509GetEncodedObjId(&pAsn1OM->otherMsgType, dwFlags,
|
|
&pTaggedOM->pszObjId, &pbExtra, &lRemainExtra);
|
|
|
|
Asn1X509GetAny(&pAsn1OM->otherMsgValue, dwFlags,
|
|
&pTaggedOM->Value, &pbExtra, &lRemainExtra);
|
|
}
|
|
|
|
*plRemainExtra = lRemainExtra;
|
|
*ppbExtra = pbExtra;
|
|
}
|
|
|
|
//+-------------------------------------------------------------------------
|
|
// CMC Data Encode (ASN1)
|
|
//--------------------------------------------------------------------------
|
|
BOOL WINAPI Asn1CmcDataEncodeEx(
|
|
IN DWORD dwCertEncodingType,
|
|
IN LPCSTR lpszStructType,
|
|
IN PCMC_DATA_INFO pInfo,
|
|
IN DWORD dwFlags,
|
|
IN OPTIONAL PCRYPT_ENCODE_PARA pEncodePara,
|
|
OUT OPTIONAL void *pvEncoded,
|
|
IN OUT DWORD *pcbEncoded
|
|
)
|
|
{
|
|
BOOL fResult;
|
|
CmcData Asn1Info;
|
|
|
|
memset(&Asn1Info, 0, sizeof(Asn1Info));
|
|
if (!Asn1CmcSetTaggedAttributes(pInfo->cTaggedAttribute,
|
|
pInfo->rgTaggedAttribute, &Asn1Info.controlSequence))
|
|
goto ErrorReturn;
|
|
if (!Asn1CmcSetTaggedRequests(pInfo->cTaggedRequest,
|
|
pInfo->rgTaggedRequest, &Asn1Info.reqSequence))
|
|
goto ErrorReturn;
|
|
if (!Asn1CmcSetTaggedContentInfos(pInfo->cTaggedContentInfo,
|
|
pInfo->rgTaggedContentInfo, &Asn1Info.cmsSequence))
|
|
goto ErrorReturn;
|
|
if (!Asn1CmcSetTaggedOtherMsgs(pInfo->cTaggedOtherMsg,
|
|
pInfo->rgTaggedOtherMsg, &Asn1Info.otherMsgSequence))
|
|
goto ErrorReturn;
|
|
|
|
fResult = Asn1InfoEncodeEx(
|
|
CmcData_PDU,
|
|
&Asn1Info,
|
|
dwFlags,
|
|
pEncodePara,
|
|
pvEncoded,
|
|
pcbEncoded
|
|
);
|
|
|
|
CommonReturn:
|
|
Asn1CmcFreeTaggedAttributes(&Asn1Info.controlSequence);
|
|
Asn1CmcFreeTaggedRequests(&Asn1Info.reqSequence);
|
|
Asn1CmcFreeTaggedContentInfos(&Asn1Info.cmsSequence);
|
|
Asn1CmcFreeTaggedOtherMsgs(&Asn1Info.otherMsgSequence);
|
|
return fResult;
|
|
|
|
ErrorReturn:
|
|
if (dwFlags & CRYPT_ENCODE_ALLOC_FLAG)
|
|
*((void **) pvEncoded) = NULL;
|
|
*pcbEncoded = 0;
|
|
fResult = FALSE;
|
|
goto CommonReturn;
|
|
}
|
|
|
|
//+-------------------------------------------------------------------------
|
|
// CMC Data Decode (ASN1)
|
|
//--------------------------------------------------------------------------
|
|
BOOL WINAPI Asn1CmcDataDecodeExCallback(
|
|
IN void *pvAsn1Info,
|
|
IN DWORD dwFlags,
|
|
IN OPTIONAL PCRYPT_DECODE_PARA pDecodePara,
|
|
OUT OPTIONAL void *pvStructInfo,
|
|
IN OUT LONG *plRemainExtra
|
|
)
|
|
{
|
|
BOOL fResult;
|
|
CmcData *pAsn1 = (CmcData *) pvAsn1Info;
|
|
PCMC_DATA_INFO pInfo = (PCMC_DATA_INFO) pvStructInfo;
|
|
LONG lRemainExtra = *plRemainExtra;
|
|
BYTE *pbExtra;
|
|
|
|
lRemainExtra -= sizeof(CMC_DATA_INFO);
|
|
if (lRemainExtra < 0) {
|
|
pbExtra = NULL;
|
|
} else {
|
|
memset(pInfo, 0, sizeof(CMC_DATA_INFO));
|
|
pbExtra = (BYTE *) pInfo + sizeof(CMC_DATA_INFO);
|
|
}
|
|
|
|
Asn1CmcGetTaggedAttributes(&pAsn1->controlSequence,
|
|
dwFlags,
|
|
&pInfo->cTaggedAttribute,
|
|
&pInfo->rgTaggedAttribute,
|
|
&pbExtra,
|
|
&lRemainExtra
|
|
);
|
|
|
|
if (!Asn1CmcGetTaggedRequests(&pAsn1->reqSequence,
|
|
dwFlags,
|
|
&pInfo->cTaggedRequest,
|
|
&pInfo->rgTaggedRequest,
|
|
&pbExtra,
|
|
&lRemainExtra
|
|
))
|
|
goto ErrorReturn;
|
|
|
|
Asn1CmcGetTaggedContentInfos(&pAsn1->cmsSequence,
|
|
dwFlags,
|
|
&pInfo->cTaggedContentInfo,
|
|
&pInfo->rgTaggedContentInfo,
|
|
&pbExtra,
|
|
&lRemainExtra
|
|
);
|
|
|
|
Asn1CmcGetTaggedOtherMsgs(&pAsn1->otherMsgSequence,
|
|
dwFlags,
|
|
&pInfo->cTaggedOtherMsg,
|
|
&pInfo->rgTaggedOtherMsg,
|
|
&pbExtra,
|
|
&lRemainExtra
|
|
);
|
|
|
|
fResult = TRUE;
|
|
CommonReturn:
|
|
*plRemainExtra = lRemainExtra;
|
|
return fResult;
|
|
|
|
ErrorReturn:
|
|
fResult = FALSE;
|
|
goto CommonReturn;
|
|
}
|
|
|
|
BOOL WINAPI Asn1CmcDataDecodeEx(
|
|
IN DWORD dwCertEncodingType,
|
|
IN LPCSTR lpszStructType,
|
|
IN const BYTE *pbEncoded,
|
|
IN DWORD cbEncoded,
|
|
IN DWORD dwFlags,
|
|
IN OPTIONAL PCRYPT_DECODE_PARA pDecodePara,
|
|
OUT OPTIONAL void *pvStructInfo,
|
|
IN OUT DWORD *pcbStructInfo
|
|
)
|
|
{
|
|
return Asn1InfoDecodeAndAllocEx(
|
|
CmcData_PDU,
|
|
pbEncoded,
|
|
cbEncoded,
|
|
dwFlags,
|
|
pDecodePara,
|
|
Asn1CmcDataDecodeExCallback,
|
|
pvStructInfo,
|
|
pcbStructInfo
|
|
);
|
|
}
|
|
|
|
|
|
//+-------------------------------------------------------------------------
|
|
// CMC Response Encode (ASN1)
|
|
//--------------------------------------------------------------------------
|
|
BOOL WINAPI Asn1CmcResponseEncodeEx(
|
|
IN DWORD dwCertEncodingType,
|
|
IN LPCSTR lpszStructType,
|
|
IN PCMC_RESPONSE_INFO pInfo,
|
|
IN DWORD dwFlags,
|
|
IN OPTIONAL PCRYPT_ENCODE_PARA pEncodePara,
|
|
OUT OPTIONAL void *pvEncoded,
|
|
IN OUT DWORD *pcbEncoded
|
|
)
|
|
{
|
|
BOOL fResult;
|
|
CmcResponseBody Asn1Info;
|
|
|
|
memset(&Asn1Info, 0, sizeof(Asn1Info));
|
|
if (!Asn1CmcSetTaggedAttributes(pInfo->cTaggedAttribute,
|
|
pInfo->rgTaggedAttribute, &Asn1Info.controlSequence))
|
|
goto ErrorReturn;
|
|
if (!Asn1CmcSetTaggedContentInfos(pInfo->cTaggedContentInfo,
|
|
pInfo->rgTaggedContentInfo, &Asn1Info.cmsSequence))
|
|
goto ErrorReturn;
|
|
if (!Asn1CmcSetTaggedOtherMsgs(pInfo->cTaggedOtherMsg,
|
|
pInfo->rgTaggedOtherMsg, &Asn1Info.otherMsgSequence))
|
|
goto ErrorReturn;
|
|
|
|
fResult = Asn1InfoEncodeEx(
|
|
CmcResponseBody_PDU,
|
|
&Asn1Info,
|
|
dwFlags,
|
|
pEncodePara,
|
|
pvEncoded,
|
|
pcbEncoded
|
|
);
|
|
CommonReturn:
|
|
Asn1CmcFreeTaggedAttributes(&Asn1Info.controlSequence);
|
|
Asn1CmcFreeTaggedContentInfos(&Asn1Info.cmsSequence);
|
|
Asn1CmcFreeTaggedOtherMsgs(&Asn1Info.otherMsgSequence);
|
|
return fResult;
|
|
|
|
ErrorReturn:
|
|
if (dwFlags & CRYPT_ENCODE_ALLOC_FLAG)
|
|
*((void **) pvEncoded) = NULL;
|
|
*pcbEncoded = 0;
|
|
fResult = FALSE;
|
|
goto CommonReturn;
|
|
}
|
|
|
|
//+-------------------------------------------------------------------------
|
|
// CMC Response Decode (ASN1)
|
|
//--------------------------------------------------------------------------
|
|
BOOL WINAPI Asn1CmcResponseDecodeExCallback(
|
|
IN void *pvAsn1Info,
|
|
IN DWORD dwFlags,
|
|
IN OPTIONAL PCRYPT_DECODE_PARA pDecodePara,
|
|
OUT OPTIONAL void *pvStructInfo,
|
|
IN OUT LONG *plRemainExtra
|
|
)
|
|
{
|
|
BOOL fResult;
|
|
CmcResponseBody *pAsn1 = (CmcResponseBody *) pvAsn1Info;
|
|
PCMC_RESPONSE_INFO pInfo = (PCMC_RESPONSE_INFO) pvStructInfo;
|
|
LONG lRemainExtra = *plRemainExtra;
|
|
BYTE *pbExtra;
|
|
|
|
lRemainExtra -= sizeof(CMC_RESPONSE_INFO);
|
|
if (lRemainExtra < 0) {
|
|
pbExtra = NULL;
|
|
} else {
|
|
memset(pInfo, 0, sizeof(CMC_RESPONSE_INFO));
|
|
pbExtra = (BYTE *) pInfo + sizeof(CMC_RESPONSE_INFO);
|
|
}
|
|
|
|
Asn1CmcGetTaggedAttributes(&pAsn1->controlSequence,
|
|
dwFlags,
|
|
&pInfo->cTaggedAttribute,
|
|
&pInfo->rgTaggedAttribute,
|
|
&pbExtra,
|
|
&lRemainExtra
|
|
);
|
|
|
|
Asn1CmcGetTaggedContentInfos(&pAsn1->cmsSequence,
|
|
dwFlags,
|
|
&pInfo->cTaggedContentInfo,
|
|
&pInfo->rgTaggedContentInfo,
|
|
&pbExtra,
|
|
&lRemainExtra
|
|
);
|
|
|
|
Asn1CmcGetTaggedOtherMsgs(&pAsn1->otherMsgSequence,
|
|
dwFlags,
|
|
&pInfo->cTaggedOtherMsg,
|
|
&pInfo->rgTaggedOtherMsg,
|
|
&pbExtra,
|
|
&lRemainExtra
|
|
);
|
|
|
|
fResult = TRUE;
|
|
*plRemainExtra = lRemainExtra;
|
|
return fResult;
|
|
}
|
|
|
|
BOOL WINAPI Asn1CmcResponseDecodeEx(
|
|
IN DWORD dwCertEncodingType,
|
|
IN LPCSTR lpszStructType,
|
|
IN const BYTE *pbEncoded,
|
|
IN DWORD cbEncoded,
|
|
IN DWORD dwFlags,
|
|
IN OPTIONAL PCRYPT_DECODE_PARA pDecodePara,
|
|
OUT OPTIONAL void *pvStructInfo,
|
|
IN OUT DWORD *pcbStructInfo
|
|
)
|
|
{
|
|
return Asn1InfoDecodeAndAllocEx(
|
|
CmcResponseBody_PDU,
|
|
pbEncoded,
|
|
cbEncoded,
|
|
dwFlags,
|
|
pDecodePara,
|
|
Asn1CmcResponseDecodeExCallback,
|
|
pvStructInfo,
|
|
pcbStructInfo
|
|
);
|
|
}
|
|
|
|
//+-------------------------------------------------------------------------
|
|
// CMC Status Encode (ASN1)
|
|
//--------------------------------------------------------------------------
|
|
BOOL WINAPI Asn1CmcStatusEncodeEx(
|
|
IN DWORD dwCertEncodingType,
|
|
IN LPCSTR lpszStructType,
|
|
IN PCMC_STATUS_INFO pInfo,
|
|
IN DWORD dwFlags,
|
|
IN OPTIONAL PCRYPT_ENCODE_PARA pEncodePara,
|
|
OUT OPTIONAL void *pvEncoded,
|
|
IN OUT DWORD *pcbEncoded
|
|
)
|
|
{
|
|
BOOL fResult;
|
|
CmcStatusInfo Asn1Info;
|
|
|
|
memset(&Asn1Info, 0, sizeof(Asn1Info));
|
|
Asn1Info.cmcStatus = pInfo->dwStatus;
|
|
if (pInfo->cBodyList) {
|
|
Asn1Info.bodyList.count = pInfo->cBodyList;
|
|
Asn1Info.bodyList.value = pInfo->rgdwBodyList;
|
|
}
|
|
|
|
if (pInfo->pwszStatusString && L'\0' != *pInfo->pwszStatusString) {
|
|
Asn1Info.bit_mask |= statusString_present;
|
|
Asn1Info.statusString.length = wcslen(pInfo->pwszStatusString);
|
|
Asn1Info.statusString.value = pInfo->pwszStatusString;
|
|
}
|
|
|
|
if (CMC_OTHER_INFO_NO_CHOICE != pInfo->dwOtherInfoChoice) {
|
|
Asn1Info.bit_mask |= otherInfo_present;
|
|
|
|
switch (pInfo->dwOtherInfoChoice) {
|
|
case CMC_OTHER_INFO_FAIL_CHOICE:
|
|
Asn1Info.otherInfo.choice = failInfo_chosen;
|
|
Asn1Info.otherInfo.u.failInfo = pInfo->dwFailInfo;
|
|
break;
|
|
case CMC_OTHER_INFO_PEND_CHOICE:
|
|
Asn1Info.otherInfo.choice = pendInfo_chosen;
|
|
Asn1X509SetOctetString(&pInfo->pPendInfo->PendToken,
|
|
&Asn1Info.otherInfo.u.pendInfo.pendToken);
|
|
if (!PkiAsn1ToGeneralizedTime(
|
|
&pInfo->pPendInfo->PendTime,
|
|
&Asn1Info.otherInfo.u.pendInfo.pendTime))
|
|
goto GeneralizedTimeError;
|
|
break;
|
|
default:
|
|
goto InvalidOtherInfoChoiceError;
|
|
}
|
|
}
|
|
|
|
|
|
fResult = Asn1InfoEncodeEx(
|
|
CmcStatusInfo_PDU,
|
|
&Asn1Info,
|
|
dwFlags,
|
|
pEncodePara,
|
|
pvEncoded,
|
|
pcbEncoded
|
|
);
|
|
|
|
CommonReturn:
|
|
return fResult;
|
|
|
|
ErrorReturn:
|
|
if (dwFlags & CRYPT_ENCODE_ALLOC_FLAG)
|
|
*((void **) pvEncoded) = NULL;
|
|
*pcbEncoded = 0;
|
|
fResult = FALSE;
|
|
goto CommonReturn;
|
|
|
|
SET_ERROR(InvalidOtherInfoChoiceError, E_INVALIDARG)
|
|
SET_ERROR(GeneralizedTimeError, CRYPT_E_BAD_ENCODE)
|
|
}
|
|
|
|
//+-------------------------------------------------------------------------
|
|
// CMC Status Decode (ASN1)
|
|
//--------------------------------------------------------------------------
|
|
BOOL WINAPI Asn1CmcStatusDecodeExCallback(
|
|
IN void *pvAsn1Info,
|
|
IN DWORD dwFlags,
|
|
IN OPTIONAL PCRYPT_DECODE_PARA pDecodePara,
|
|
OUT OPTIONAL void *pvStructInfo,
|
|
IN OUT LONG *plRemainExtra
|
|
)
|
|
{
|
|
BOOL fResult;
|
|
CmcStatusInfo *pAsn1 = (CmcStatusInfo *) pvAsn1Info;
|
|
PCMC_STATUS_INFO pInfo = (PCMC_STATUS_INFO) pvStructInfo;
|
|
LONG lRemainExtra = *plRemainExtra;
|
|
LONG lAlignExtra;
|
|
BYTE *pbExtra;
|
|
|
|
lRemainExtra -= sizeof(CMC_STATUS_INFO);
|
|
if (lRemainExtra < 0) {
|
|
pbExtra = NULL;
|
|
} else {
|
|
memset(pInfo, 0, sizeof(CMC_STATUS_INFO));
|
|
pbExtra = (BYTE *) pInfo + sizeof(CMC_STATUS_INFO);
|
|
|
|
pInfo->dwStatus = pAsn1->cmcStatus;
|
|
}
|
|
|
|
if (pAsn1->bodyList.count > 0) {
|
|
ASN1uint32_t count = pAsn1->bodyList.count;
|
|
|
|
lAlignExtra = INFO_LEN_ALIGN(count * sizeof(DWORD));
|
|
lRemainExtra -= lAlignExtra;
|
|
if (lRemainExtra >= 0) {
|
|
BodyPartID *value;
|
|
DWORD *pdwBodyList;
|
|
|
|
value = pAsn1->bodyList.value;
|
|
pdwBodyList = (DWORD *) pbExtra;
|
|
pbExtra += lAlignExtra;
|
|
|
|
pInfo->cBodyList = count;
|
|
pInfo->rgdwBodyList = pdwBodyList;
|
|
|
|
for ( ; count > 0; count--, value++, pdwBodyList++)
|
|
*pdwBodyList = *value;
|
|
}
|
|
}
|
|
|
|
|
|
if (pAsn1->bit_mask & statusString_present) {
|
|
ASN1uint32_t length = pAsn1->statusString.length;
|
|
|
|
lAlignExtra = INFO_LEN_ALIGN((length + 1) * sizeof(WCHAR));
|
|
lRemainExtra -= lAlignExtra;
|
|
if (lRemainExtra >= 0) {
|
|
memcpy(pbExtra, pAsn1->statusString.value, length * sizeof(WCHAR));
|
|
memset(pbExtra + (length * sizeof(WCHAR)), 0, sizeof(WCHAR));
|
|
|
|
pInfo->pwszStatusString = (LPWSTR) pbExtra;
|
|
pbExtra += lAlignExtra;
|
|
}
|
|
}
|
|
|
|
if (pAsn1->bit_mask & otherInfo_present) {
|
|
switch (pAsn1->otherInfo.choice) {
|
|
case failInfo_chosen:
|
|
if (lRemainExtra >= 0) {
|
|
pInfo->dwOtherInfoChoice = CMC_OTHER_INFO_FAIL_CHOICE;
|
|
pInfo->dwFailInfo = pAsn1->otherInfo.u.failInfo;
|
|
}
|
|
break;
|
|
case pendInfo_chosen:
|
|
{
|
|
PCMC_PEND_INFO pPendInfo;
|
|
|
|
lAlignExtra = INFO_LEN_ALIGN(sizeof(CMC_PEND_INFO));
|
|
lRemainExtra -= lAlignExtra;
|
|
if (lRemainExtra >= 0) {
|
|
pInfo->dwOtherInfoChoice = CMC_OTHER_INFO_PEND_CHOICE;
|
|
pPendInfo = (PCMC_PEND_INFO) pbExtra;
|
|
pInfo->pPendInfo = pPendInfo;
|
|
pbExtra += lAlignExtra;
|
|
|
|
if (!PkiAsn1FromGeneralizedTime(
|
|
&pAsn1->otherInfo.u.pendInfo.pendTime,
|
|
&pPendInfo->PendTime))
|
|
goto GeneralizedTimeDecodeError;
|
|
} else
|
|
pPendInfo = NULL;
|
|
|
|
Asn1X509GetOctetString(
|
|
&pAsn1->otherInfo.u.pendInfo.pendToken, dwFlags,
|
|
&pPendInfo->PendToken, &pbExtra, &lRemainExtra);
|
|
}
|
|
break;
|
|
default:
|
|
goto InvalidOtherInfoChoiceError;
|
|
}
|
|
}
|
|
|
|
fResult = TRUE;
|
|
CommonReturn:
|
|
*plRemainExtra = lRemainExtra;
|
|
return fResult;
|
|
ErrorReturn:
|
|
fResult = FALSE;
|
|
goto CommonReturn;
|
|
SET_ERROR(InvalidOtherInfoChoiceError, CRYPT_E_BAD_ENCODE)
|
|
SET_ERROR(GeneralizedTimeDecodeError, CRYPT_E_BAD_ENCODE)
|
|
}
|
|
|
|
BOOL WINAPI Asn1CmcStatusDecodeEx(
|
|
IN DWORD dwCertEncodingType,
|
|
IN LPCSTR lpszStructType,
|
|
IN const BYTE *pbEncoded,
|
|
IN DWORD cbEncoded,
|
|
IN DWORD dwFlags,
|
|
IN OPTIONAL PCRYPT_DECODE_PARA pDecodePara,
|
|
OUT OPTIONAL void *pvStructInfo,
|
|
IN OUT DWORD *pcbStructInfo
|
|
)
|
|
{
|
|
return Asn1InfoDecodeAndAllocEx(
|
|
CmcStatusInfo_PDU,
|
|
pbEncoded,
|
|
cbEncoded,
|
|
dwFlags,
|
|
pDecodePara,
|
|
Asn1CmcStatusDecodeExCallback,
|
|
pvStructInfo,
|
|
pcbStructInfo
|
|
);
|
|
}
|
|
|
|
|
|
//+-------------------------------------------------------------------------
|
|
// CMC Add Extensions Encode (ASN1)
|
|
//--------------------------------------------------------------------------
|
|
BOOL WINAPI Asn1CmcAddExtensionsEncodeEx(
|
|
IN DWORD dwCertEncodingType,
|
|
IN LPCSTR lpszStructType,
|
|
IN PCMC_ADD_EXTENSIONS_INFO pInfo,
|
|
IN DWORD dwFlags,
|
|
IN OPTIONAL PCRYPT_ENCODE_PARA pEncodePara,
|
|
OUT OPTIONAL void *pvEncoded,
|
|
IN OUT DWORD *pcbEncoded
|
|
)
|
|
{
|
|
BOOL fResult;
|
|
CmcAddExtensions Asn1Info;
|
|
|
|
memset(&Asn1Info, 0, sizeof(Asn1Info));
|
|
Asn1Info.pkiDataReference = pInfo->dwCmcDataReference;
|
|
if (pInfo->cCertReference) {
|
|
Asn1Info.certReferences.count = pInfo->cCertReference;
|
|
Asn1Info.certReferences.value = pInfo->rgdwCertReference;
|
|
}
|
|
|
|
if (!Asn1X509SetExtensions(pInfo->cExtension, pInfo->rgExtension,
|
|
&Asn1Info.extensions))
|
|
goto ErrorReturn;
|
|
|
|
fResult = Asn1InfoEncodeEx(
|
|
CmcAddExtensions_PDU,
|
|
&Asn1Info,
|
|
dwFlags,
|
|
pEncodePara,
|
|
pvEncoded,
|
|
pcbEncoded
|
|
);
|
|
|
|
CommonReturn:
|
|
Asn1X509FreeExtensions(&Asn1Info.extensions);
|
|
return fResult;
|
|
|
|
ErrorReturn:
|
|
if (dwFlags & CRYPT_ENCODE_ALLOC_FLAG)
|
|
*((void **) pvEncoded) = NULL;
|
|
*pcbEncoded = 0;
|
|
fResult = FALSE;
|
|
goto CommonReturn;
|
|
}
|
|
|
|
|
|
//+-------------------------------------------------------------------------
|
|
// CMC Add Extensions Decode (ASN1)
|
|
//--------------------------------------------------------------------------
|
|
BOOL WINAPI Asn1CmcAddExtensionsDecodeExCallback(
|
|
IN void *pvAsn1Info,
|
|
IN DWORD dwFlags,
|
|
IN OPTIONAL PCRYPT_DECODE_PARA pDecodePara,
|
|
OUT OPTIONAL void *pvStructInfo,
|
|
IN OUT LONG *plRemainExtra
|
|
)
|
|
{
|
|
BOOL fResult;
|
|
CmcAddExtensions *pAsn1 = (CmcAddExtensions *) pvAsn1Info;
|
|
PCMC_ADD_EXTENSIONS_INFO pInfo = (PCMC_ADD_EXTENSIONS_INFO) pvStructInfo;
|
|
LONG lRemainExtra = *plRemainExtra;
|
|
LONG lAlignExtra;
|
|
BYTE *pbExtra;
|
|
|
|
lRemainExtra -= sizeof(CMC_ADD_EXTENSIONS_INFO);
|
|
if (lRemainExtra < 0) {
|
|
pbExtra = NULL;
|
|
} else {
|
|
memset(pInfo, 0, sizeof(CMC_ADD_EXTENSIONS_INFO));
|
|
pbExtra = (BYTE *) pInfo + sizeof(CMC_ADD_EXTENSIONS_INFO);
|
|
|
|
pInfo->dwCmcDataReference = pAsn1->pkiDataReference;
|
|
}
|
|
|
|
if (pAsn1->certReferences.count > 0) {
|
|
ASN1uint32_t count = pAsn1->certReferences.count;
|
|
|
|
lAlignExtra = INFO_LEN_ALIGN(count * sizeof(DWORD));
|
|
lRemainExtra -= lAlignExtra;
|
|
if (lRemainExtra >= 0) {
|
|
BodyPartID *value;
|
|
DWORD *pdwCertReference;
|
|
|
|
value = pAsn1->certReferences.value;
|
|
pdwCertReference = (DWORD *) pbExtra;
|
|
pbExtra += lAlignExtra;
|
|
|
|
pInfo->cCertReference = count;
|
|
pInfo->rgdwCertReference = pdwCertReference;
|
|
|
|
for ( ; count > 0; count--, value++, pdwCertReference++)
|
|
*pdwCertReference = *value;
|
|
}
|
|
}
|
|
|
|
Asn1X509GetExtensions(&pAsn1->extensions, dwFlags,
|
|
&pInfo->cExtension, &pInfo->rgExtension, &pbExtra, &lRemainExtra);
|
|
|
|
fResult = TRUE;
|
|
*plRemainExtra = lRemainExtra;
|
|
return fResult;
|
|
}
|
|
|
|
BOOL WINAPI Asn1CmcAddExtensionsDecodeEx(
|
|
IN DWORD dwCertEncodingType,
|
|
IN LPCSTR lpszStructType,
|
|
IN const BYTE *pbEncoded,
|
|
IN DWORD cbEncoded,
|
|
IN DWORD dwFlags,
|
|
IN OPTIONAL PCRYPT_DECODE_PARA pDecodePara,
|
|
OUT OPTIONAL void *pvStructInfo,
|
|
IN OUT DWORD *pcbStructInfo
|
|
)
|
|
{
|
|
return Asn1InfoDecodeAndAllocEx(
|
|
CmcAddExtensions_PDU,
|
|
pbEncoded,
|
|
cbEncoded,
|
|
dwFlags,
|
|
pDecodePara,
|
|
Asn1CmcAddExtensionsDecodeExCallback,
|
|
pvStructInfo,
|
|
pcbStructInfo
|
|
);
|
|
}
|
|
|
|
//+-------------------------------------------------------------------------
|
|
// CMC Add Attributes Encode (ASN1)
|
|
//--------------------------------------------------------------------------
|
|
BOOL WINAPI Asn1CmcAddAttributesEncodeEx(
|
|
IN DWORD dwCertEncodingType,
|
|
IN LPCSTR lpszStructType,
|
|
IN PCMC_ADD_ATTRIBUTES_INFO pInfo,
|
|
IN DWORD dwFlags,
|
|
IN OPTIONAL PCRYPT_ENCODE_PARA pEncodePara,
|
|
OUT OPTIONAL void *pvEncoded,
|
|
IN OUT DWORD *pcbEncoded
|
|
)
|
|
{
|
|
BOOL fResult;
|
|
CmcAddAttributes Asn1Info;
|
|
|
|
memset(&Asn1Info, 0, sizeof(Asn1Info));
|
|
Asn1Info.pkiDataReference = pInfo->dwCmcDataReference;
|
|
if (pInfo->cCertReference) {
|
|
Asn1Info.certReferences.count = pInfo->cCertReference;
|
|
Asn1Info.certReferences.value = pInfo->rgdwCertReference;
|
|
}
|
|
|
|
if (!Asn1X509SetAttributes(pInfo->cAttribute, pInfo->rgAttribute,
|
|
&Asn1Info.attributes))
|
|
goto ErrorReturn;
|
|
|
|
fResult = Asn1InfoEncodeEx(
|
|
CmcAddAttributes_PDU,
|
|
&Asn1Info,
|
|
dwFlags,
|
|
pEncodePara,
|
|
pvEncoded,
|
|
pcbEncoded
|
|
);
|
|
|
|
CommonReturn:
|
|
Asn1X509FreeAttributes(&Asn1Info.attributes);
|
|
return fResult;
|
|
|
|
ErrorReturn:
|
|
if (dwFlags & CRYPT_ENCODE_ALLOC_FLAG)
|
|
*((void **) pvEncoded) = NULL;
|
|
*pcbEncoded = 0;
|
|
fResult = FALSE;
|
|
goto CommonReturn;
|
|
}
|
|
|
|
|
|
//+-------------------------------------------------------------------------
|
|
// CMC Add Attributes Decode (ASN1)
|
|
//--------------------------------------------------------------------------
|
|
BOOL WINAPI Asn1CmcAddAttributesDecodeExCallback(
|
|
IN void *pvAsn1Info,
|
|
IN DWORD dwFlags,
|
|
IN OPTIONAL PCRYPT_DECODE_PARA pDecodePara,
|
|
OUT OPTIONAL void *pvStructInfo,
|
|
IN OUT LONG *plRemainExtra
|
|
)
|
|
{
|
|
BOOL fResult;
|
|
CmcAddAttributes *pAsn1 = (CmcAddAttributes *) pvAsn1Info;
|
|
PCMC_ADD_ATTRIBUTES_INFO pInfo = (PCMC_ADD_ATTRIBUTES_INFO) pvStructInfo;
|
|
LONG lRemainExtra = *plRemainExtra;
|
|
LONG lAlignExtra;
|
|
BYTE *pbExtra;
|
|
|
|
lRemainExtra -= sizeof(CMC_ADD_ATTRIBUTES_INFO);
|
|
if (lRemainExtra < 0) {
|
|
pbExtra = NULL;
|
|
} else {
|
|
memset(pInfo, 0, sizeof(CMC_ADD_ATTRIBUTES_INFO));
|
|
pbExtra = (BYTE *) pInfo + sizeof(CMC_ADD_ATTRIBUTES_INFO);
|
|
|
|
pInfo->dwCmcDataReference = pAsn1->pkiDataReference;
|
|
}
|
|
|
|
if (pAsn1->certReferences.count > 0) {
|
|
ASN1uint32_t count = pAsn1->certReferences.count;
|
|
|
|
lAlignExtra = INFO_LEN_ALIGN(count * sizeof(DWORD));
|
|
lRemainExtra -= lAlignExtra;
|
|
if (lRemainExtra >= 0) {
|
|
BodyPartID *value;
|
|
DWORD *pdwCertReference;
|
|
|
|
value = pAsn1->certReferences.value;
|
|
pdwCertReference = (DWORD *) pbExtra;
|
|
pbExtra += lAlignExtra;
|
|
|
|
pInfo->cCertReference = count;
|
|
pInfo->rgdwCertReference = pdwCertReference;
|
|
|
|
for ( ; count > 0; count--, value++, pdwCertReference++)
|
|
*pdwCertReference = *value;
|
|
}
|
|
}
|
|
|
|
Asn1X509GetAttributes(&pAsn1->attributes, dwFlags,
|
|
&pInfo->cAttribute, &pInfo->rgAttribute, &pbExtra, &lRemainExtra);
|
|
|
|
fResult = TRUE;
|
|
*plRemainExtra = lRemainExtra;
|
|
return fResult;
|
|
}
|
|
|
|
BOOL WINAPI Asn1CmcAddAttributesDecodeEx(
|
|
IN DWORD dwCertEncodingType,
|
|
IN LPCSTR lpszStructType,
|
|
IN const BYTE *pbEncoded,
|
|
IN DWORD cbEncoded,
|
|
IN DWORD dwFlags,
|
|
IN OPTIONAL PCRYPT_DECODE_PARA pDecodePara,
|
|
OUT OPTIONAL void *pvStructInfo,
|
|
IN OUT DWORD *pcbStructInfo
|
|
)
|
|
{
|
|
return Asn1InfoDecodeAndAllocEx(
|
|
CmcAddAttributes_PDU,
|
|
pbEncoded,
|
|
cbEncoded,
|
|
dwFlags,
|
|
pDecodePara,
|
|
Asn1CmcAddAttributesDecodeExCallback,
|
|
pvStructInfo,
|
|
pcbStructInfo
|
|
);
|
|
}
|
|
|
|
//+=========================================================================
|
|
// Certificate Template Encode/Decode Functions
|
|
//==========================================================================
|
|
|
|
BOOL WINAPI Asn1X509CertTemplateEncodeEx(
|
|
IN DWORD dwCertEncodingType,
|
|
IN LPCSTR lpszStructType,
|
|
IN PCERT_TEMPLATE_EXT pInfo,
|
|
IN DWORD dwFlags,
|
|
IN OPTIONAL PCRYPT_ENCODE_PARA pEncodePara,
|
|
OUT OPTIONAL void *pvEncoded,
|
|
IN OUT DWORD *pcbEncoded
|
|
)
|
|
{
|
|
BOOL fResult;
|
|
CertificateTemplate Asn1Info;
|
|
|
|
memset(&Asn1Info, 0, sizeof(Asn1Info));
|
|
if (!Asn1X509SetEncodedObjId(pInfo->pszObjId, &Asn1Info.templateID))
|
|
goto ErrorReturn;
|
|
|
|
Asn1Info.templateMajorVersion = pInfo->dwMajorVersion;
|
|
if (pInfo->fMinorVersion) {
|
|
Asn1Info.bit_mask |= templateMinorVersion_present;
|
|
Asn1Info.templateMinorVersion = pInfo->dwMinorVersion;
|
|
}
|
|
|
|
fResult = Asn1InfoEncodeEx(
|
|
CertificateTemplate_PDU,
|
|
&Asn1Info,
|
|
dwFlags,
|
|
pEncodePara,
|
|
pvEncoded,
|
|
pcbEncoded
|
|
);
|
|
|
|
goto CommonReturn;
|
|
|
|
ErrorReturn:
|
|
if (dwFlags & CRYPT_ENCODE_ALLOC_FLAG)
|
|
*((void **) pvEncoded) = NULL;
|
|
*pcbEncoded = 0;
|
|
fResult = FALSE;
|
|
CommonReturn:
|
|
return fResult;
|
|
}
|
|
|
|
BOOL WINAPI Asn1X509CertTemplateDecodeExCallback(
|
|
IN void *pvAsn1Info,
|
|
IN DWORD dwFlags,
|
|
IN OPTIONAL PCRYPT_DECODE_PARA pDecodePara,
|
|
OUT OPTIONAL void *pvStructInfo,
|
|
IN OUT LONG *plRemainExtra
|
|
)
|
|
{
|
|
CertificateTemplate *pAsn1Info = (CertificateTemplate *) pvAsn1Info;
|
|
PCERT_TEMPLATE_EXT pInfo =
|
|
(PCERT_TEMPLATE_EXT) pvStructInfo;
|
|
LONG lRemainExtra = *plRemainExtra;
|
|
BYTE *pbExtra;
|
|
|
|
lRemainExtra -= sizeof(CERT_TEMPLATE_EXT);
|
|
if (lRemainExtra < 0) {
|
|
pbExtra = NULL;
|
|
} else {
|
|
memset(pInfo, 0, sizeof(CERT_TEMPLATE_EXT));
|
|
pbExtra = (BYTE *) pInfo + sizeof(CERT_TEMPLATE_EXT);
|
|
|
|
pInfo->dwMajorVersion = pAsn1Info->templateMajorVersion;
|
|
if (pAsn1Info->bit_mask & templateMinorVersion_present) {
|
|
pInfo->fMinorVersion = TRUE;
|
|
pInfo->dwMinorVersion = pAsn1Info->templateMinorVersion;
|
|
}
|
|
}
|
|
|
|
Asn1X509GetEncodedObjId(&pAsn1Info->templateID, dwFlags,
|
|
&pInfo->pszObjId, &pbExtra, &lRemainExtra);
|
|
|
|
*plRemainExtra = lRemainExtra;
|
|
return TRUE;
|
|
}
|
|
|
|
BOOL WINAPI Asn1X509CertTemplateDecodeEx(
|
|
IN DWORD dwCertEncodingType,
|
|
IN LPCSTR lpszStructType,
|
|
IN const BYTE *pbEncoded,
|
|
IN DWORD cbEncoded,
|
|
IN DWORD dwFlags,
|
|
IN OPTIONAL PCRYPT_DECODE_PARA pDecodePara,
|
|
OUT OPTIONAL void *pvStructInfo,
|
|
IN OUT DWORD *pcbStructInfo
|
|
)
|
|
{
|
|
return Asn1InfoDecodeAndAllocEx(
|
|
CertificateTemplate_PDU,
|
|
pbEncoded,
|
|
cbEncoded,
|
|
dwFlags,
|
|
pDecodePara,
|
|
Asn1X509CertTemplateDecodeExCallback,
|
|
pvStructInfo,
|
|
pcbStructInfo
|
|
);
|
|
}
|