⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 dname.c

📁 vc环境下的pgp源码
💻 C
📖 第 1 页 / 共 4 页
字号:
	    /* 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 + -