#include "SecAsn1Coder.h"
#include "plarenas.h"
#include "prerror.h"
#include "seccomon.h"
#include "secasn1.h"
#include <Security/SecBase.h>
#define CHUNKSIZE_DEF 1024
typedef struct SecAsn1Coder {
PLArenaPool *mPool;
} SecAsn1Coder_t;
OSStatus SecAsn1CoderCreate(
SecAsn1CoderRef *coder)
{
if(coder == NULL) {
return errSecParam;
}
SecAsn1CoderRef _coder = (SecAsn1CoderRef)malloc(sizeof(SecAsn1Coder_t));
_coder->mPool = PORT_NewArena(CHUNKSIZE_DEF);
if(_coder->mPool == NULL) {
free(_coder);
return errSecAllocate;
}
*coder = _coder;
return errSecSuccess;
}
OSStatus SecAsn1CoderRelease(
SecAsn1CoderRef coder)
{
if(coder == NULL) {
return errSecParam;
}
if(coder->mPool != NULL) {
PORT_FreeArena(coder->mPool, PR_TRUE);
coder->mPool = NULL;
}
free(coder);
return errSecSuccess;
}
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 errSecParam;
}
SECStatus prtn = SEC_ASN1Decode(coder->mPool, dest, templ, (const char *)src, len);
if(prtn) {
return errSecDecode;
}
else {
return errSecSuccess;
}
}
OSStatus SecAsn1DecodeData(
SecAsn1CoderRef coder,
const SecAsn1Item *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,
SecAsn1Item *dest)
{
if((coder == NULL) || (src == NULL) || (templ == NULL) || (dest == NULL)) {
return errSecParam;
}
dest->Data = NULL;
dest->Length = 0;
SecAsn1Item *rtnItem = SEC_ASN1EncodeItem(coder->mPool, dest, src, templ);
if(rtnItem == NULL) {
return errSecParam;
}
else {
return errSecSuccess;
}
}
void *SecAsn1Malloc(
SecAsn1CoderRef coder,
size_t len)
{
if(coder == NULL) {
return NULL;
}
return PORT_ArenaAlloc(coder->mPool, len);
}
OSStatus SecAsn1AllocItem(
SecAsn1CoderRef coder,
SecAsn1Item *item,
size_t len)
{
if((coder == NULL) || (item == NULL)) {
return errSecParam;
}
item->Data = (uint8_t *)PORT_ArenaAlloc(coder->mPool, len);
if(item->Data == NULL) {
return errSecAllocate;
}
item->Length = len;
return errSecSuccess;
}
OSStatus SecAsn1AllocCopy(
SecAsn1CoderRef coder,
const void *src,
size_t len,
SecAsn1Item *dest)
{
if(src == NULL) {
return errSecParam;
}
OSStatus ortn = SecAsn1AllocItem(coder, dest, len);
if(ortn) {
return ortn;
}
memmove(dest->Data, src, len);
return errSecSuccess;
}
OSStatus SecAsn1AllocCopyItem(
SecAsn1CoderRef coder,
const SecAsn1Item *src,
SecAsn1Item *dest)
{
return SecAsn1AllocCopy(coder, src->Data, src->Length, dest);
}
bool SecAsn1OidCompare(const SecAsn1Oid *oid1, const SecAsn1Oid *oid2) {
if (!oid1 || !oid2)
return oid1 == oid2;
if (oid1->Length != oid2->Length)
return false;
return !memcmp(oid1->Data, oid2->Data, oid1->Length);
}