#include "SecAsn1Coder.h"
#include <security_asn1/plarenas.h>
#include <security_asn1/prerror.h>
#include <security_asn1/seccomon.h>
#include <security_asn1/secasn1.h>
#include <CoreServices/../Frameworks/CarbonCore.framework/Headers/MacErrors.h>
#define CHUNKSIZE_DEF 1024
typedef struct SecAsn1Coder {
PLArenaPool *mPool;
} SecAsn1Coder_t;
OSStatus SecAsn1CoderCreate(
SecAsn1CoderRef *coder)
{
if(coder == NULL) {
return paramErr;
}
SecAsn1Coder *_coder = (SecAsn1CoderRef)malloc(sizeof(SecAsn1Coder_t));
_coder->mPool = PORT_NewArena(CHUNKSIZE_DEF);
if(_coder->mPool == NULL) {
return memFullErr;
}
*coder = _coder;
return noErr;
}
OSStatus SecAsn1CoderRelease(
SecAsn1CoderRef coder)
{
if(coder == NULL) {
return paramErr;
}
if(coder->mPool != NULL) {
PORT_FreeArena(coder->mPool, PR_TRUE);
coder->mPool = NULL;
}
free(coder);
return noErr;
}
OSStatus SecAsn1Decode(
SecAsn1CoderRef coder,
const void *src, size_t len,
const SecAsn1Template *templ,
void *dest)
{
if((coder == NULL) || (src == NULL) || (templ == NULL) || (dest == NULL)) {
return paramErr;
}
SECStatus prtn = SEC_ASN1Decode(coder->mPool, dest, templ, (const char *)src, len);
if(prtn) {
return errSecUnknownFormat;
}
else {
return noErr;
}
}
OSStatus SecAsn1DecodeData(
SecAsn1CoderRef coder,
const CSSM_DATA *src,
const SecAsn1Template *templ,
void *dest)
{
return SecAsn1Decode(coder, src->Data, src->Length, templ, dest);
}
OSStatus SecAsn1EncodeItem(
SecAsn1CoderRef coder,
const void *src,
const SecAsn1Template *templ,
CSSM_DATA *dest)
{
if((coder == NULL) || (src == NULL) || (templ == NULL) || (dest == NULL)) {
return paramErr;
}
dest->Data = NULL;
dest->Length = 0;
SECItem *rtnItem = SEC_ASN1EncodeItem(coder->mPool, dest, src, templ);
if(rtnItem == NULL) {
return paramErr;
}
else {
return noErr;
}
}
void *SecAsn1Malloc(
SecAsn1CoderRef coder,
size_t len)
{
if(coder == NULL) {
return NULL;
}
return PORT_ArenaAlloc(coder->mPool, len);
}
OSStatus SecAsn1AllocItem(
SecAsn1CoderRef coder,
CSSM_DATA *item,
size_t len)
{
if((coder == NULL) || (item == NULL)) {
return paramErr;
}
item->Data = (uint8 *)PORT_ArenaAlloc(coder->mPool, len);
if(item->Data == NULL) {
return memFullErr;
}
item->Length = len;
return noErr;
}
OSStatus SecAsn1AllocCopy(
SecAsn1CoderRef coder,
const void *src,
size_t len,
CSSM_DATA *dest)
{
if(src == NULL) {
return paramErr;
}
OSStatus ortn = SecAsn1AllocItem(coder, dest, len);
if(ortn) {
return ortn;
}
memmove(dest->Data, src, len);
return noErr;
}
OSStatus SecAsn1AllocCopyItem(
SecAsn1CoderRef coder,
const CSSM_DATA *src,
CSSM_DATA *dest)
{
return SecAsn1AllocCopy(coder, src->Data, src->Length, dest);
}