|
|
//+--------------------------------------------------------------------------
//
// Microsoft Windows
// Copyright (C) Microsoft Corporation, 1996 - 1999
//
// File: crypt.cpp
//
// Contents: Cert Server wrapper routines
//
// History: 17-Oct-96 vich created
//
//---------------------------------------------------------------------------
#include <pch.cpp>
#pragma hdrstop
#include <stdlib.h>
#define CRYPT32_SP3_ONLY
#ifdef CRYPT32_SP3_ONLY
#ifdef __cplusplus
extern "C" { #endif
#include "keygen.h"
#ifdef __cplusplus
} #endif
#include "crypttls.h"
#include "ossconv.h"
#include "ossutil.h"
// All the *pInfo extra stuff needs to be aligned
#define INFO_LEN_ALIGN(Len) (((Len) + 7) & ~7)
HCRYPTOSSGLOBAL hOssGlobal;
//+-------------------------------------------------------------------------
// Function: GetPog
//
// Synopsis: Initialize thread local storage for the asn libs
//
// Returns: pointer to an initialized OssGlobal data structure
//--------------------------------------------------------------------------
__inline OssGlobal * GetPog(VOID) { return(I_CryptGetOssGlobal(hOssGlobal)); }
HRESULT HError(VOID) { HRESULT hr;
hr = GetLastError(); if (hr <= 0xffff) { hr = HRESULT_FROM_WIN32(hr); }
if (!FAILED(hr)) { // somebody failed a call without properly setting an error condition
hr = E_UNEXPECTED; } return(hr); }
VOID OssX509GetIA5ConvertedToUnicode( IN IA5STRING *pOss, IN DWORD dwFlags, OPTIONAL OUT LPWSTR *ppwsz, IN OUT BYTE **ppbExtra, IN OUT LONG *plRemainExtra) { OssUtilGetIA5StringConvertedToUnicode( pOss->length, pOss->value, dwFlags, ppwsz, ppbExtra, plRemainExtra); }
VOID OssX509GetObjectId( IN ObjectID *pOss, IN DWORD dwFlags, OPTIONAL OUT CHAR **pInfo, IN OUT BYTE **ppbExtra, IN OUT LONG *plRemainExtra) { DWORD cb; DWORD cbExtra; char ach[MAX_PATH]; LONG lRemainExtra;
cb = sizeof(ach); if (!OssConvFromObjectIdentifier(pOss->count, pOss->value, ach, &cb)) { goto error; } CSASSERT(strlen(ach) + 1 == cb); cbExtra = INFO_LEN_ALIGN(cb);
lRemainExtra = *plRemainExtra; lRemainExtra -= cbExtra; if (0 <= lRemainExtra) { *pInfo = (char *) *ppbExtra; CopyMemory(*pInfo, ach, cb); *ppbExtra += cbExtra; } *plRemainExtra = lRemainExtra;
error: ; }
__inline VOID OssX509GetAlgorithmParameters( IN OpenType *pOss, IN DWORD dwFlags, OPTIONAL OUT CRYPT_OBJID_BLOB *pInfo, IN OUT BYTE **ppbExtra, IN OUT LONG *plRemainExtra) { OssUtilGetOctetString( pOss->length, (BYTE *) pOss->encoded, dwFlags, pInfo, ppbExtra, plRemainExtra); }
VOID OssX509GetAlgorithm( IN AlgorithmIdentifier *pOss, IN DWORD dwFlags, OPTIONAL OUT CRYPT_ALGORITHM_IDENTIFIER *pInfo, IN OUT BYTE **ppbExtra, IN OUT LONG *plRemainExtra) { if (0 <= *plRemainExtra) { ZeroMemory((VOID *) pInfo, sizeof(*pInfo)); } OssX509GetObjectId( &pOss->algorithm, dwFlags, &pInfo->pszObjId, ppbExtra, plRemainExtra);
if (pOss->bit_mask & parameters_present) { OssX509GetAlgorithmParameters( &pOss->parameters, dwFlags, &pInfo->Parameters, ppbExtra, plRemainExtra); } }
__inline VOID OssX509GetPublicKeyBlob( IN BITSTRING const *pOss, IN DWORD dwFlags, OPTIONAL OUT CRYPT_BIT_BLOB *pInfo, IN OUT BYTE **ppbExtra, IN OUT LONG *plRemainExtra) { OssUtilGetBitString( pOss->length, pOss->value, dwFlags, pInfo, ppbExtra, plRemainExtra); }
VOID OssX509GetPublicKeyInfo( IN SubjectPublicKeyInfo *pOss, IN DWORD dwFlags, OPTIONAL OUT CERT_PUBLIC_KEY_INFO *pInfo, IN OUT BYTE **ppbExtra, IN OUT LONG *plRemainExtra) { OssX509GetAlgorithm( &pOss->algorithm, dwFlags, &pInfo->Algorithm, ppbExtra, plRemainExtra);
OssX509GetPublicKeyBlob( &pOss->subjectPublicKey, dwFlags, &pInfo->PublicKey, ppbExtra, plRemainExtra); } //+-------------------------------------------------------------------------
// Decode into an allocated, OSS formatted info structure
//
// Called by the OssX509*Decode() functions.
//--------------------------------------------------------------------------
__inline BOOL OssInfoDecodeAndAlloc( IN int pdunum, IN const BYTE *pbEncoded, IN DWORD cbEncoded, OUT VOID **ppOssInfo) { return(OssUtilDecodeAndAllocInfo( GetPog(), pdunum, pbEncoded, cbEncoded, ppOssInfo)); }
//+-------------------------------------------------------------------------
// Free an allocated, OSS formatted info structure
//
// Called by the OssX509*Decode() functions.
//--------------------------------------------------------------------------
VOID OssInfoFree( IN int pdunum, IN VOID *pOssInfo) { if (NULL != pOssInfo) { DWORD dwErr = GetLastError();
// TlsGetValue globbers LastError
OssUtilFreeInfo(GetPog(), pdunum, pOssInfo); SetLastError(dwErr); } }
//+-------------------------------------------------------------------------
// KeyGen Info Decode (OSS X509)
//--------------------------------------------------------------------------
BOOL DecodeKeyGen( IN BYTE const *pbEncoded, IN DWORD cbEncoded, IN DWORD dwFlags, OUT VOID *pInfo, IN OUT DWORD *pcbInfo) { BOOL fResult = FALSE; HRESULT hr; SignedPublicKeyAndChallenge *pOssInfo = NULL; CERT_KEYGEN_REQUEST_INFO *pcgi; BYTE *pbExtra; LONG lRemainExtra; LONG lAlignExtra;
if (pInfo == NULL) { *pcbInfo = 0; } if (0 == hOssGlobal) { hOssGlobal = I_CryptInstallOssGlobal(keygen, 0, NULL); if (0 == hOssGlobal) { goto error; } } if (!OssInfoDecodeAndAlloc( SignedPublicKeyAndChallenge_PDU, pbEncoded, cbEncoded, (VOID **) &pOssInfo)) { hr = HError(); printf("OssInfoDecodeAndAlloc returned %u (%x)\n", hr, hr); goto error; }
lRemainExtra = (LONG) *pcbInfo - INFO_LEN_ALIGN(sizeof(*pcgi)); pbExtra = NULL;
// for lRemainExtra < 0, LENGTH_ONLY calculation
if (0 <= lRemainExtra) { pcgi = (CERT_KEYGEN_REQUEST_INFO *) pInfo;
// Default all optional fields to zero
ZeroMemory((VOID *) pcgi, sizeof(*pcgi)); pcgi->dwVersion = 1;
pbExtra = (BYTE *) pcgi + INFO_LEN_ALIGN(sizeof(*pcgi)); }
OssX509GetPublicKeyInfo( &pOssInfo->publicKeyAndChallenge.spki, dwFlags, &pcgi->SubjectPublicKeyInfo, &pbExtra, &lRemainExtra);
OssX509GetIA5ConvertedToUnicode( &pOssInfo->publicKeyAndChallenge.challenge, dwFlags, &pcgi->pwszChallengeString, &pbExtra, &lRemainExtra);
if (0 <= lRemainExtra) { *pcbInfo = *pcbInfo - (DWORD) lRemainExtra; } else { *pcbInfo = *pcbInfo + (DWORD) -lRemainExtra; if (NULL != pInfo) { SetLastError(HRESULT_FROM_WIN32(ERROR_MORE_DATA)); goto error; } } fResult = TRUE;
error: OssInfoFree(SignedPublicKeyAndChallenge_PDU, pOssInfo); if (!fResult) { *pcbInfo = 0; } return(fResult); } #endif
BOOL myDecodeKeyGenRequest( IN BYTE const *pbRequest, IN DWORD cbRequest, OUT CERT_KEYGEN_REQUEST_INFO **ppKeyGenRequest, OUT DWORD *pcbKeyGenRequest) { BOOL fOk = FALSE;
#ifdef CRYPT32_SP3_ONLY
*ppKeyGenRequest = NULL; *pcbKeyGenRequest = 0;
if (!DecodeKeyGen( pbRequest, cbRequest, 0, // dwFlags
NULL, pcbKeyGenRequest)) { goto error; } *ppKeyGenRequest = (CERT_KEYGEN_REQUEST_INFO *) LocalAlloc(LMEM_FIXED, *pcbKeyGenRequest); if (NULL == *ppKeyGenRequest) { _PrintError(E_OUTOFMEMORY, "LocalAlloc(KeyGenRequest)"); SetLastError(E_OUTOFMEMORY); goto error; }
if (!DecodeKeyGen( pbRequest, cbRequest, 0, // dwFlags
*ppKeyGenRequest, pcbKeyGenRequest)) { goto error; } #else
if (!myDecodeObject( X509_ASN_ENCODING, X509_KEYGEN_REQUEST_TO_BE_SIGNED, pbRequest, cbRequest, (VOID **) ppKeyGenRequest, pcbKeyGenRequest)) { err = myHLastError(); _JumpError(err, error, "myDecodeObject"); } #endif
fOk = TRUE;
error: return(fOk); }
|