📄 dname.c
字号:
/* a delimited comma */
else if ( *(comma-1) == '\\' ) {
namePos = comma + 1;
continue;
}
else {
namePos = comma + 1;
*comma = '\0';
TrimWS(rdnStart);
break;
}
} /* for(;;) */
/* we have an RDN */
rdnSeq->elt[rdnSeq->n] =
TC_Alloc(context->memMgr, sizeof(PKIRelativeDistinguishedName));
if (rdnSeq->elt[rdnSeq->n] == NULL) {
/* rest of structure freed in top level routine */
TC_Free(context->memMgr, buf);
return TC_E_NOMEMORY;
}
memset(rdnSeq->elt[rdnSeq->n], 0,
sizeof(PKIRelativeDistinguishedName));
rdnName = (PKIRelativeDistinguishedName *)rdnSeq->elt[rdnSeq->n];
if ((status = ParseStringRDN(rdnName, rdnStart, context)) != 0) {
/* on error free the one we just allocated, rest
of structure freed in top level routine */
PKIFreeRelativeDistinguishedName(context->certasnctx,
rdnSeq->elt[rdnSeq->n]);
rdnSeq->elt[rdnSeq->n] = NULL;
TC_Free(context->memMgr, buf);
return status;
}
rdnSeq->n++;
} /* while rdnNames */
if (rdnSeq->n >= PKIMAX_RDNSequence && namePos != '\0') {
/* structure free'd at top level routine */
TC_Free(context->memMgr, buf);
return TC_E_NAMETOOLONG;
}
TC_Free(context->memMgr, buf);
return 0;
} /* ParseStringRDNSeq */
int ParseStringRDN(
PKIRelativeDistinguishedName *rdn,
const char *name,
TC_CONTEXT *context)
{
PKIAttributeTypeAndValue *ava;
char *rdnPos, *avaStart, *plus;
char *buf;
int status;
if (!rdn)
return TC_E_INVARGS;
/* see if the structure is already full */
if (rdn->n == PKIMAX_RelativeDistinguishedName) {
return TC_E_NAMETOOLONG;
}
buf = TC_Alloc(context->memMgr, strlen(name)+1);
if (buf == NULL)
return TC_E_NOMEMORY;
strcpy(buf, name);
rdnPos = buf;
while(rdnPos != '\0' && rdn->n < PKIMAX_RelativeDistinguishedName) {
SKIPWS(rdnPos);
avaStart = rdnPos;
while(1) {
plus = strchr(rdnPos, '+');
if (plus == NULL) { /* last ava in string */
TrimWS(avaStart);
rdnPos = '\0';
break;
}
else if (*(plus-1) == '\\') { /* delimited */
rdnPos = plus + 1;
continue;
}
else {
rdnPos = plus + 1;
*plus = '\0';
TrimWS(avaStart);
break;
}
} /* while(0) */
/* we have an AVA */
rdn->elt[rdn->n] = TC_Alloc(context->memMgr,
sizeof(PKIAttributeTypeAndValue));
if (rdn->elt[rdn->n] == NULL) {
TC_Free(context->memMgr, buf);
return TC_E_NOMEMORY;
}
memset(rdn->elt[rdn->n], 0, sizeof(PKIAttributeTypeAndValue));
ava = (PKIAttributeTypeAndValue *)rdn->elt[rdn->n];
if ((status = ParseStringAVA(ava, avaStart, context)) != 0) {
/* free the one we just allocated, rest of structure is freed
in top level routine */
PKIFreeAttributeTypeAndValue(context->certasnctx, rdn->elt[rdn->n]);
rdn->elt[rdn->n] = NULL;
TC_Free(context->memMgr, buf);
return status;
}
rdn->n++;
} /* while avas */
if (rdn->n >= PKIMAX_RelativeDistinguishedName && rdnPos != '\0') {
/* structure free'd at top level routine */
TC_Free(context->memMgr, buf);
return TC_E_NAMETOOLONG;
}
TC_Free(context->memMgr, buf);
return 0;
} /* ParseStringRDN */
static int ParseStringAVA(
PKIAttributeTypeAndValue *ava,
const char *name,
TC_CONTEXT *context)
{
char *oidStr, *valStr, *equal, *dot;
unsigned char *hexOID, *der;
size_t hexOIDLen, derLen;
TC_AVA_ENTRY *avaInfo;
unsigned char *undelimitedStr;
size_t length;
char *buf;
int status = 0;
if (!ava)
return TC_E_INVARGS;
buf = TC_Alloc(context->memMgr, strlen(name)+1);
if (buf == NULL)
return TC_E_NOMEMORY;
strcpy(buf, name);
equal = strchr(buf, '=');
if (equal == NULL) {
TC_Free(context->memMgr, buf);
return TC_E_DNAMEPARSE;
}
oidStr = buf;
valStr = equal + 1;
*equal = '\0';
SKIPWS(oidStr);
SKIPWS(valStr);
TrimWS(oidStr);
TrimWS(valStr);
dot = strchr(oidStr, '.');
if (dot != NULL) { /* its a dotted decimal OID */
status = tc_create_oid(&hexOID, &hexOIDLen, oidStr, context);
if (status != 0 || hexOID == NULL) {
TC_Free(context->memMgr, buf);
return TC_E_DNAMEPARSE;
}
if (valStr[0] != '#') {
TC_Free(context->memMgr, hexOID);
TC_Free(context->memMgr, buf);
return TC_E_DNAMEPARSE;
}
status = HexStringToUchar(&der, &derLen, valStr+1, context->memMgr);
if (status != 0 || der == NULL) {
TC_Free(context->memMgr, hexOID);
TC_Free(context->memMgr, buf);
return status;
}
(void)tc_set_avader(ava,
hexOID,
hexOIDLen,
der,
derLen,
context);
TC_Free(context->memMgr, hexOID);
TC_Free(context->memMgr, der);
}
else { /* it must be an oid name in the context list */
avaInfo = lookupASNtype(oidStr, context);
if (avaInfo == NULL) {
TC_Free(context->memMgr, buf);
return TC_E_DNAMEPARSE;
}
if (UndelimitString(&undelimitedStr, &length,
valStr, context->memMgr) != 0) {
TC_Free(context->memMgr, buf);
return TC_E_DNAMEPARSE;
}
/* This call will return an error if the provided string value
is not correct for the ASN.1 type */
/* TODO: idea, add a flag in context table that says whether
ava value's ASN.1 type can be changed as needed, especially
if the type is DirectoryString. */
status = CreateAVADERFromString(undelimitedStr, length, avaInfo,
&der, &derLen, context);
if (status != 0) {
TC_Free(context->memMgr, buf);
TC_Free(context->memMgr, undelimitedStr);
return status;
}
(void)tc_set_avader (ava,
avaInfo->oid,
avaInfo->oidlen,
der,
derLen,
context);
TC_Free(context->memMgr, undelimitedStr);
TC_Free(context->memMgr, der);
}
TC_Free(context->memMgr, buf);
return 0;
} /* ParseStringAVA */
static int
UndelimitString(
unsigned char **converted, size_t *length, const char *orig,
TC_MemoryMgr *mgr)
{
char *p = (char *)orig;
unsigned char *new;
size_t newlen = 0;
if (!converted)
return TC_E_INVARGS;
*converted = NULL;
new = TC_Alloc(mgr, strlen(orig));
if (new == NULL)
return TC_E_NOMEMORY;
*converted = new;
while (*p != '\0') {
if (*p == '\\') {
p++;
switch(*p) {
case '"':
case '=':
case ',':
case '+':
case '\\':
case '<':
case '>':
case ';':
case '#':
case ' ':
*new = *p;
new++; p++;
newlen++;
break;
case '\0':
TC_Free(mgr, *converted);
*converted = NULL;
return TC_E_DNAMEPARSE;
break;
default:
if (HexCharsToUchar(new, p) != 0) {
TC_Free(mgr, *converted);
*converted = NULL;
return TC_E_DNAMEPARSE;
}
p += 2;
new ++;
newlen++;
break;
} /* switch */
} /* if delimiter */
else {
*new = *p;
new++; p++;
newlen++;
}
} /* while chars */
*length = newlen;
return 0;
} /* UndelimitString */
static int HexCharsToUchar(
unsigned char *hex, char *string)
{
char buf[2];
unsigned char c1 = 0, c2 = 0;
if (!hex || !string)
return TC_E_INVARGS;
strncpy(buf, string, 2);
buf[0] = toupper(buf[0]);
if ( (buf[0] > 0x46) || (buf[0] < 0x30) ||
((buf[0] > 0x39) && (buf[0] < 0x41)) )
return TC_E_DNAMEPARSE; /* Outside hex range */
c1 = buf[0] - 0x30;
if (buf[0] > 0x39)
c1 = c1-7;
buf[1] = toupper(buf[1]);
if ( (buf[1] > 0x46) || (buf[1] < 0x30) ||
((buf[1] > 0x39) && (buf[1] < 0x41)) )
return TC_E_DNAMEPARSE; /* Outside hex range */
c2 = buf[1] - 0x30;
if (buf[1] > 0x39)
c2 = c2 - 7;
c1 = (c1 << 4) | (0x00ff & c2);
*hex = c1;
return 0;
} /* HexCharsToUchar */
/*****
*
* HexStringToUchar
*
* Convert a NULL terminated string version of hexidecimal characters into
* an unsigned char array of the actual hex characters. Every
* pair of hex string characters is converted into one unsigned char.
* If the provided string has an odd number of characters, then the
* string is prepended with "0" before conversion.
*
*****/
static int HexStringToUchar(
unsigned char **der,
size_t *derlen,
const char *hexstr,
TC_MemoryMgr *mgr)
{
size_t stringLen = 0;
char *localstring;
size_t localstringlen;
unsigned char *localder;
size_t localderlen;
unsigned char *ptr;
unsigned int i;
int status;
if (!der || !hexstr || !derlen)
return TC_E_INVARGS;
*der = NULL;
*derlen = 0;
stringLen = strlen(hexstr);
if (stringLen == 0) /* don't have chars to convert */
return 0;
/* see if its odd or even length */
if ( (stringLen%2) == 0) {
localderlen = stringLen/2;
localstringlen = stringLen;
localstring = TC_Alloc(mgr, stringLen + 1);
if (localstring == NULL)
return TC_E_NOMEMORY;
strcpy(localstring, (char *)hexstr);
}
else {
localderlen = stringLen/2 + 1;
localstringlen = stringLen + 1;
/* allocate a local copy of string prepended with "0" */
localstring = TC_Alloc(mgr,
stringLen + 2); /* 1 for prepended 0 and 1 for '\0' */
if (localstring == NULL)
return TC_E_NOMEMORY;
strcpy(localstring, "0");
strcat(localstring, hexstr);
}
/* allocate local work space */
localder = TC_Alloc(mgr, localderlen);
if (localder == NULL) {
TC_Free(mgr, localstring);
return TC_E_NOMEMORY;
}
ptr = localder;
for (i = 0; i < localstringlen; i += 2) {
if ((status = HexCharsToUchar(ptr, localstring+i)) != 0) {
TC_Free(mgr, localstring);
TC_Free(mgr, localder);
return status;
}
ptr++;
}
*der = localder;
*derlen = localderlen;
TC_Free(mgr, localstring);
return 0;
} /* HexStringToUchar */
/*****
*
* UcharToHexString
*
*****/
static char *UcharToHexString(
unsigned char *buf,
size_t buflen,
TC_MemoryMgr *mgr)
{
char *hexString;
size_t hexStringLen;
char temp[4];
unsigned int i;
/* two hex chars for each byte + '\0' */
hexStringLen = buflen*2 +1;
hexString = TC_Alloc(mgr, hexStringLen);
if (hexString == NULL)
return NULL;
hexString[0] = '\0';
for (i = 0; i < buflen; i++) {
sprintf(temp, "%02x", buf[i]);
strcat(hexString, temp);
}
return hexString;
} /* UcharToHexString */
/****
*
* DelimitString
*
* Add backslashes to delimit characters in text strings based
* on the syntax defined in RFC 2253
*
*****/
static char *DelimitString(
unsigned char *buf,
size_t buflen,
TC_MemoryMgr *mgr)
{
char *delimString;
char *delimStringPtr;
unsigned int i,j;
size_t delimStringLen = buflen;
size_t numLeadingSpaces = 0;
size_t numTrailingSpaces = 0;
if (buflen == 0) {
delimString = TC_Alloc(mgr, 1);
if (delimString == NULL)
return NULL;
*delimString = '\0';
return delimString;
}
/*----- calc the additional size of the delimiters in the string ----*/
/* We need to delimit leading and ending space characters, but not
any other spaces */
i = 0;
while (buf[i] == ' ') {
numLeadingSpaces++;
i++;
}
/* check to see if the string is all spaces, if not then see if there
are any trailing spaces */
if (numLeadingSpaces != buflen) {
i = buflen - 1;
while (buf[i] == ' ' && (int)i >= 0) {
numTrailingSpaces++;
i--;
}
}
delimStringLen = delimStringLen + numLeadingSpaces + numTrailingSpaces;
for (i = 0; i < buflen; i++) {
switch(buf[i]) {
case '"':
case '=':
case ',':
case '+':
case '\\':
case '<':
case '>':
case ';':
case '#':
delimStringLen++;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -