/* * Copyright (c) 2000-2001 Apple Computer, Inc. All Rights Reserved. * * The contents of this file constitute Original Code as defined in and are * subject to the Apple Public Source License Version 1.2 (the 'License'). * You may not use this file except in compliance with the License. Please obtain * a copy of the License at http://www.apple.com/publicsource and read it before * using this file. * * This Original Code and all software distributed under the License are * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS * OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, INCLUDING WITHOUT * LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR * PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. Please see the License for the * specific language governing rights and limitations under the License. */ /* @(#) sm_vdasnacc.h 1.21 5/1/98 09:59:08 */ // vdasnacc.h // #ifndef _SM_VDASNACC_H_ #define _SM_VDASNACC_H_ #include "asn-incl.h" #include #ifndef SM_SIZE_T #define SM_SIZE_T size_t #endif #ifdef WIN32 #include #define SM_FOPEN_WRITE "wb" #define SM_FOPEN_READ "rb" #define SM_FOPEN_APPEND "ab" #else #define SM_FOPEN_WRITE "w" #define SM_FOPEN_READ "r" #define SM_FOPEN_APPEND "a" #endif ////////////////////////////////////////////////////////////////////////// // CSM_Buffer is the general purpose buffer used throughout the SFL class CSM_Buffer: public AsnType { private: SM_SIZE_T m_lSize; char *m_pMemory; #if !defined(macintosh) && !defined(__APPLE__) char *m_pszFN; FILE *m_pFP; #endif char *m_pMemFP; char *m_pCache; SM_SIZE_T m_lCacheSize; #if !defined(macintosh) && !defined(__APPLE__) // returns bool value indicating if the buffer is in a file bool InFile() { if (m_pszFN == NULL) return false; else return true; } #endif // AllocMoreMem allocates specified more bytes for mem buffer void AllocMoreMem(SM_SIZE_T lSize); public: // CONSTRUCTORS // use this constructor to create a complete empty buffer CSM_Buffer(); // use this constructor to create a memory buffer of size lSize CSM_Buffer(size_t lSize); // use this constructor to create a buffer in file pszFileName //CSM_Buffer(char *pszFileName); // use this constructor to init the memory buffer with a ptr and size CSM_Buffer(const char *pBuf, SM_SIZE_T lSize); // use this constructor to make a copy of the provided buffer // and put it into this buffer CSM_Buffer(const CSM_Buffer &b); virtual ~CSM_Buffer(); // DESTRUCTOR // Inheirited from AsnType. virtual AsnType *Clone() const; virtual AsnType *Copy() const; virtual AsnLen BEnc (BUF_TYPE b); void Print (ostream &os) const; // CONTENT MODIFYING MEMBERS void Clear(); // ATTRIBUTE MEMBERS // return size of the buffer SM_SIZE_T Length() const; // copy the provided null terminated memory in memory buffer void Set(const char *psz); // copy the provided memory of size lSize in memory buffer void Set(const char *p, SM_SIZE_T lSize); // set the length of the buffer void SetLength(SM_SIZE_T lSize) { m_lSize = lSize; } #if !defined(macintosh) && !defined(__APPLE__) // copy the provided file name into m_pszFN void SetFileName(char *pszFN) { #ifdef HAVE_STRDUP strdup(pszFN); #else m_pszFN = (char *)malloc (strlen (pszFN) + 1); strcpy (m_pszFN, pszFN); #endif } #endif // allocate memory in the buffer and return ptr to it char* Alloc(SM_SIZE_T lSize); // compare this with b, return 0 if match long Compare(const CSM_Buffer &b); // ReSet copies b into this long ReSet(const CSM_Buffer &b); // BUFFER DATA ACCESS MEMBERS // return a pointer to the actual data, if in file, call CopyAll const char* Access() const; // return a copy of the actual data and return the size char* Get(SM_SIZE_T &l) const; // return a copy of the actual data char* Get() const { SM_SIZE_T l; return Get(l); } // COMPARISON OPERATORS bool operator == (/*const*/ CSM_Buffer &b) { if (Compare(b) == 0) return true; else return false; } bool operator != (/*const*/ CSM_Buffer &b) { if (Compare(b) == 0) return false; else return true; } // ASSIGNMENT OPERATOR CSM_Buffer &operator = (/*const*/ CSM_Buffer &b) { ReSet(b); return *this; } #if !defined(macintosh) && !defined(__APPLE__) // BUFFER CONVERSION MEMBERS long ConvertFileToMemory(); long ConvertMemoryToFile(char *pszFN); #endif // STREAMING MEMBERS long Open(char *pszMode); long Seek(SM_SIZE_T lOffset, SM_SIZE_T lOrigin); void Close(); // STREAMING MEMBERS long cRead(char *pBuffer, SM_SIZE_T lSize); long Write(const char *pBuffer, SM_SIZE_T lSize); char* nRead(SM_SIZE_T lSize, SM_SIZE_T &lBytesRead); void Flush(); }; long vdasnacc_sortSet(CSM_Buffer *pEncBuf[], int icount); long vdasnacc_sortSetOf(CSM_Buffer **&pEncBuf, int icount); long SM_WriteToAsnBuf(CSM_Buffer *&pCBuf, AsnBuf &SNACCinputBuf); long SM_WriteToAsnBuf(CSM_Buffer &CBuf, AsnBuf &SNACCoutputBuf); long SM_ReadFromAsnBuf(CSM_Buffer *&pCBuf, // OUT,copied data. AsnBuf &SNACCinputBuf, // IN, input SNACC buffer long length, // IN, length of data to read. CSM_Buffer *preLoad); // IN, optional data to be pre-loaded; // (for SNACC support) // no alloc version of SM_ReadFromAsnBuf long SM_ReadFromAsnBuf( AsnBuf &SNACCinputBuf, // IN, input SNACC buffer CSM_Buffer *pCBuf, // OUT,copied data. long length, // IN, length of data to read. CSM_Buffer *preLoad); // IN, optional data to be pre-loaded; // (for SNACC support) // function to convert an AsnBits to a CSM_Buffer long SM_AsnBits2Buffer(AsnBits *pBits, CSM_Buffer *pBuffer); long SM_Buffer2AsnBits(CSM_Buffer *pBuffer, AsnBits *pBits, size_t lBits); long SM_BufferReverseBits(CSM_Buffer *pBuffer); class BigIntegerStr; #define SM_BUF_2_BIG_INT_STR 0 #if SM_BUF_2_BIG_INT_STR // FIXME - why doesn't this link properly? // prototypes for converting to and from BigIntegerStr and CSM_Buffer. long SM_Buffer2BigIntegerStr( CSM_Buffer *asn1Data, BigIntegerStr &pSnaccBigIntStr, bool unsignedFlag); long SM_Buffer2BigIntegerStr( CSM_Buffer *asn1Data, BigIntegerStr *&pSnaccBigIntStr, bool unsignedFlag); #endif /* SM_BUF_2_BIG_INT_STR */ // VDASNACC_ENCDEC_BUFSIZE is the number of bytes in the global // buffer used for encoding and decoding #define VDASNACC_ENCDEC_BUFSIZE 100000 //typedef struct //{ // long lgth; /* Number of characters in string */ // unsigned char *str; /* Pointer to character string */ //} Str_struct; #define NULL_STR (Str_struct *) NULL //extern "C" { //#include /**** Standard I/O includes ****/ //long vdasnacc_sortSetOf(Str_struct **strEnc, int icount); //long vdasnacc_sortSet(Str_struct **strEnc, int icount); //void free_Str(Str_struct *str); //void free_Str_content(Str_struct *str); //} #if SNACC_ENABLE_PDU /* Note no equivalent if !SNACC_ENABLE_PDU */ #define ENCODE_ANY(encodedData,asnAny)\ {\ CSM_Buffer *blob=new CSM_Buffer;\ \ if ((encodedData) && (asnAny))\ {\ ENCODE_BUF((encodedData), blob)\ (asnAny)->value = (AsnType *)blob;\ }\ } #define DECODE_ANY(decodeData,asnAny)\ {\ CSM_Buffer *blob;\ if ((asnAny))\ blob=(CSM_Buffer *)(asnAny)->value;\ \ if (blob)\ DECODE_BUF((decodeData), blob)\ } #define ENCODE_BUF_NO_ALLOC(encodeData, blob)\ {\ char *pchBuffer = (char *)calloc(1, \ VDASNACC_ENCDEC_BUFSIZE);\ size_t encodedLen;\ AsnBuf outputBuf;\ int status=0;\ \ outputBuf.Init(pchBuffer, VDASNACC_ENCDEC_BUFSIZE);\ outputBuf.ResetInWriteRvsMode();\ status = (encodeData)->BEncPdu (outputBuf, encodedLen);\ outputBuf.ResetInReadMode();\ SM_ReadFromAsnBuf(outputBuf, (blob), outputBuf.DataLen(),NULL);\ free(pchBuffer);\ } #define ENCODE_BUF(encodeData, blob)\ {\ char *pchBuffer = (char *)calloc(1, \ VDASNACC_ENCDEC_BUFSIZE);\ size_t encodedLen;\ AsnBuf outputBuf;\ int status=0;\ \ outputBuf.Init(pchBuffer, VDASNACC_ENCDEC_BUFSIZE);\ outputBuf.ResetInWriteRvsMode();\ if((status = (encodeData)->BEncPdu (outputBuf, encodedLen))==false)\ SME_THROW(33, "BAD SNACC Encode", NULL);\ outputBuf.ResetInReadMode();\ SM_ReadFromAsnBuf((blob), outputBuf, outputBuf.DataLen(),NULL);\ free(pchBuffer);\ } #define DECODE_BUF(decodeData, blob)\ {\ char *pchBuffer = (char *)calloc(1, \ VDASNACC_ENCDEC_BUFSIZE);\ size_t encodedLen;\ AsnBuf outputBuf;\ int nDecStatus = 0;\ \ outputBuf.Init(pchBuffer, VDASNACC_ENCDEC_BUFSIZE);\ outputBuf.ResetInWriteRvsMode();\ SM_WriteToAsnBuf((blob), outputBuf);\ outputBuf.ResetInReadMode();\ if ((nDecStatus = (decodeData)->BDecPdu(outputBuf, encodedLen)) == false)\ SME_THROW(34, "BAD SNACC Decode", NULL);\ free(pchBuffer);\ } #endif /* SNACC_ENABLE_PDU */ // This macro is usually only necessary if a SNACC AsnBuf is used // immediately after being loaded by an application (e.g. consecutive // encode decode operations). #define SNACC_BUFRESET_READ(pSnaccBuf) (pSnaccBuf)->ResetInReadMode(); #define SNACC_BUFRESET_WRITE(pSnaccBuf) (pSnaccBuf)->ResetInWriteRvsMode(); #define SM_ASSIGN_ANYBUF(lpBuf, asnAny)\ {\ (asnAny)->value = (AsnType *)new CSM_Buffer(*(lpBuf));\ } /* don't know if this actually works... dave */ #define SM_EXTRACT_ANYBUF(pSS, asnAny)\ {\ (pSS) = new CSM_Buffer(*(CSM_Buffer *)(asnAny)->value);\ } #define ENCODE_BUF1(encodeContent, encodeLen)\ {\ AsnBuf outputBuf;\ char *lpszBuf;\ \ lpszBuf = (char *)calloc(1, VDASNACC_ENCDEC_BUFSIZE/2);\ outputBuf.Init(lpszBuf, VDASNACC_ENCDEC_BUFSIZE/2);\ outputBuf.ResetInWriteRvsMode();\ (encodeLen) = encodeContent(outputBuf); #define ENCODE_BUF2(blob)\ outputBuf.ResetInReadMode();\ SM_ReadFromAsnBuf((blob), outputBuf, outputBuf.DataLen(),NULL);\ free(lpszBuf);\ } // RWC; The following macro defines the ASN ANY load for "BEnc...()" // RWC; operations into the final output buffers. NO ERROR checking // RWC; is performed to be sure the buffer is ASN decodable. // RWC; this convention for loading ANY results is only valid for // RWC; the SMIME/MSP library loads, where previous logic has // RWC; loaded the "AsnType *value" element with a "CSM_Buffer *" // RWC; containing the encoded ANY result. // RWC; The "Str_struct *" needs to be freed when class destroyed. // RWC; Place encoded ASN directly into buffer. #if defined(macintosh) || defined(__APPLE__) #define ENC_LOAD_ANYBUF(asnType, Bbuf, l) \ if ((asnType)->value != NULL)\ {\ l = (asnType)->value->BEnc(Bbuf);\ } #else #define ENC_LOAD_ANYBUF(asnType, Bbuf, l) \ if ((CSM_Buffer *)(asnType)->value != NULL)\ {\ SM_WriteToAsnBuf(((CSM_Buffer *&)(asnType)->value), Bbuf);\ l = ((CSM_Buffer *)(asnType)->value)->Length();\ } #endif // RWC; The following macro decodes the ANY buffer tag and length to // RWC; allocate a "CSM_Buffer", then copies the unencoded results. // RWC; The assumption is that the "readloc" buffer will still be intact // RWC; even after the decode of the tag and length. (HOPEFULLY!) // RWC; Once the data for this ANY is copied, unencoded into the CSM_Buffer // RWC; then we set the buffer "readloc" pointer to after this element. // RWC; "bBuf.GetSeg(elmtLen)" #define DEC_LOAD_ANYBUF(asnType, Bbuf, l, env) \ {\ size_t len = (size_t) 0; \ AsnLen bytesDecoded = 0L; \ size_t elmtLen = (size_t) 0; \ int tag = 0 ; \ char *readloc = NULL; \ CSM_Buffer *blob; \ CSM_Buffer *preLoad;\ \ readloc = Bbuf.GetSeg (&len);\ tag = BDecTag (Bbuf, bytesDecoded, env);\ elmtLen = BDecLen (Bbuf, bytesDecoded, env);\ len = bytesDecoded;\ preLoad = new CSM_Buffer(readloc, len);\ SM_ReadFromAsnBuf(blob, (Bbuf), elmtLen,preLoad);\ (asnType)->value = blob;\ delete preLoad;\ l += len + elmtLen;\ } // RWC; Correctly process our OID values, the "char *" "asnOid->Set()" function // directly loads the "->oid" private variable, no processing!!! //int SM_STR_TO_OID(char *lpStrOid, AsnOid *asnOid); //int SM_OID_TO_STR(char *lpStrOid, AsnOid *asnOid); #ifdef BOB #define SNACC_OID_FIX(asnOid, long_arr4) \ {\ unsigned long int a[11];\ int i;\ for (i=0; i < (long_arr4)->lgth; i++) a[i] = (long_arr4)->int_arr[i];\ for (i=(long_arr4)->lgth; i < 11; i++) a[i] = -1;\ (asnOid)->Set(a[0], a[1], a[2], a[3], a[4], a[5], a[6], a[7], a[8], a[9],\ a[10]);\ } #endif #endif // _SM_VDASNACC_H_ // EOF vdasnacc.h