#include <Security/cssmtype.h>
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
#include "cuOidParser.h"
#include "cuFileIo.h"
#include <fcntl.h>
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#define CONFIG_FILE_NAME "dumpasn1.cfg"
static const char *CONFIG_FILE1 = "../" CONFIG_FILE_NAME;
static const char *CONFIG_FILE2 = CONFIG_FILE_NAME;
#define CONFIG_FILE_ENV "LOCAL_BUILD_DIR"
static const char *OID_ENTRY_START = "OID = ";
static const char *OID_DESCR_START = "Description = ";
static
int readFileExtra(
const char *fileName,
unsigned extraBytes,
unsigned char **bytes, CSSM_SIZE *numBytes) {
int rtn;
int fd;
unsigned char *buf = NULL;
struct stat sb;
size_t size;
*numBytes = 0;
*bytes = NULL;
fd = open(fileName, O_RDONLY, 0);
if(fd < 0) {
return 1;
}
rtn = fstat(fd, &sb);
if(rtn) {
goto errOut;
}
size = (size_t)sb.st_size;
buf = (unsigned char *)malloc(size + extraBytes);
if(buf == NULL) {
rtn = ENOMEM;
goto errOut;
}
rtn = (int)read(fd, buf, (size_t)size);
if(rtn != (int)size) {
free(buf);
if(rtn >= 0) {
printf("readFile: short read\n");
}
rtn = EIO;
}
else {
rtn = 0;
*bytes = buf;
*numBytes = size;
}
errOut:
close(fd);
return rtn;
}
static CSSM_DATA_PTR readConfig()
{
CSSM_DATA_PTR configData = NULL;
int rtn;
configData = (CSSM_DATA_PTR)malloc(sizeof(CSSM_DATA));
if(configData == NULL) {
return NULL;
}
rtn = readFileExtra(CONFIG_FILE1, 1, &configData->Data,
&configData->Length);
if(rtn) {
rtn = readFileExtra(CONFIG_FILE2, 1, &configData->Data,
&configData->Length);
}
if(rtn) {
char *localBuildDir = getenv(CONFIG_FILE_ENV);
if(localBuildDir == NULL) {
rtn = 1;
}
else {
char *pathBuf = NULL;
rtn = asprintf(&pathBuf, "%s/%s", localBuildDir, CONFIG_FILE_NAME);
if (rtn < 1 || !pathBuf) {
rtn = 1;
}
else {
rtn = readFileExtra(pathBuf, 1, &configData->Data,
&configData->Length);
}
if (pathBuf) {
free(pathBuf);
}
}
}
if(rtn == 0) {
configData->Data[configData->Length++] = '\0';
return configData;
}
else {
free(configData);
return NULL;
}
}
static CSSM_BOOL parseOidWithConfig(
const CSSM_DATA_PTR configData,
const CSSM_OID_PTR oid,
char *strBuf)
{
char *fullOidStr = NULL;
char *ourEntry = NULL;
char *nextEntry = NULL;
char *descStart = NULL;
char *cp;
unsigned i;
CSSM_BOOL brtn;
char *nextCr; char *nextNl; char *eol; int len;
if(configData == NULL) {
return CSSM_FALSE;
}
fullOidStr = (char *)malloc((3 * oid->Length) +
strlen(OID_ENTRY_START) + 6 + 1); if(fullOidStr == NULL) {
return CSSM_FALSE;
}
sprintf(fullOidStr, "OID = 06 %02X", (unsigned)oid->Length);
cp = fullOidStr + strlen(fullOidStr);
for(i=0; i<oid->Length; i++) {
cp += strlen(cp);
sprintf(cp, " %02X", oid->Data[i]);
}
ourEntry = strstr((char *)configData->Data, fullOidStr);
if(ourEntry == NULL) {
brtn = CSSM_FALSE;
goto errOut;
}
nextEntry = strstr(ourEntry+1, OID_ENTRY_START);
descStart = strstr(ourEntry+1, OID_DESCR_START);
if( (descStart == NULL) || ( (descStart > nextEntry) && (nextEntry != NULL) ) ) { brtn = CSSM_FALSE;
goto errOut;
}
descStart += strlen(OID_DESCR_START);
nextNl = strchr(descStart, '\n');
nextCr = strchr(descStart, '\r');
if((nextNl == NULL) && (nextCr == NULL)) {
eol = (char *)configData->Data + configData->Length;
}
else if(nextCr == NULL) {
eol = nextNl;
}
else if(nextNl == NULL) {
eol = nextCr;
}
else if(nextNl < nextCr) {
eol = nextNl;
}
else {
eol = nextCr;
}
len = (int)(eol - descStart);
if(len > (OID_PARSER_STRING_SIZE - 1)) {
len = OID_PARSER_STRING_SIZE - 1;
}
memcpy(strBuf, descStart, len);
strBuf[len] = '\0';
brtn = CSSM_TRUE;
errOut:
if(fullOidStr != NULL) {
free(fullOidStr);
}
return brtn;
}
OidParser::OidParser(bool noConfig)
{
if(noConfig) {
configData = NULL;
}
else {
configData = readConfig();
}
}
OidParser::~OidParser()
{
if(configData == NULL) {
return;
}
if(configData->Data != NULL) {
free(configData->Data);
}
free(configData);
}
void OidParser::oidParse(
const unsigned char *oidp,
unsigned oidLen,
char *strBuf)
{
unsigned i;
CSSM_OID oid;
oid.Data = (uint8 *)oidp;
oid.Length = oidLen;
if((oidLen == 0) || (oidp == NULL)) {
strcpy(strBuf, "EMPTY");
return;
}
if(parseOidWithConfig(configData, &oid, strBuf) == CSSM_FALSE) {
char cbuf[8];
sprintf(strBuf, "OID : < 06 %02X ", (unsigned)oid.Length);
for(i=0; i<oid.Length; i++) {
sprintf(cbuf, "%02X ", oid.Data[i]);
strcat(strBuf, cbuf);
}
strcat(strBuf, ">");
}
}