Leaked source code of windows server 2003
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

//+-------------------------------------------------------------------------
//
// 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
);
}