alg1485.c

来自「支持SSL v2/v3, TLS, PKCS #5, PKCS #7, PKCS」· C语言 代码 · 共 971 行 · 第 1/2 页

C
971
字号
	CERTRDN *tmp;		/* get first one */	firstRdn = name->rdns;		/* find last one */	lastRdn = name->rdns;	while (*lastRdn) lastRdn++;	lastRdn--;		/* reverse list */	for ( ; firstRdn < lastRdn; firstRdn++, lastRdn--) {	    tmp = *firstRdn;	    *firstRdn = *lastRdn;	    *lastRdn = tmp;	}    }        /* return result */    return name;      loser:    CERT_DestroyName(name);    return NULL;}CERTName *CERT_AsciiToName(char *string){    CERTName *name;    name = ParseRFC1485Name(string, PORT_Strlen(string));    return name;}/************************************************************************/static SECStatusAppendStr(char **bufp, unsigned *buflenp, char *str){    char *buf;    unsigned bufLen, bufSize, len;    /* Figure out how much to grow buf by (add in the '\0') */    buf = *bufp;    bufLen = *buflenp;    len = PORT_Strlen(str);    bufSize = bufLen + len;    if (buf) {	buf = (char*) PORT_Realloc(buf, bufSize);    } else {	bufSize++;	buf = (char*) PORT_Alloc(bufSize);    }    if (!buf) {	PORT_SetError(SEC_ERROR_NO_MEMORY);	return SECFailure;    }    *bufp = buf;    *buflenp = bufSize;    /* Concatenate str onto buf */    buf = buf + bufLen;    if (bufLen) buf--;			/* stomp on old '\0' */    PORT_Memcpy(buf, str, len+1);		/* put in new null */    return SECSuccess;}SECStatusCERT_RFC1485_EscapeAndQuote(char *dst, int dstlen, char *src, int srclen){    int i, reqLen=0;    char *d = dst;    PRBool needsQuoting = PR_FALSE;        /* need to make an initial pass to determine if quoting is needed */    for (i = 0; i < srclen; i++) {	char c = src[i];	reqLen++;	if (SPECIAL_CHAR(c)) {	    /* entirety will need quoting */	    needsQuoting = PR_TRUE;	}	if (c == C_DOUBLE_QUOTE || c == C_BACKSLASH) {	    /* this char will need escaping */	    reqLen++;	}    }    /* if it begins or ends in optional space it needs quoting */    if (srclen > 0 &&	(OPTIONAL_SPACE(src[srclen-1]) || OPTIONAL_SPACE(src[0]))) {	needsQuoting = PR_TRUE;    }        if (needsQuoting) reqLen += 2;    /* space for terminal null */    reqLen++;        if (reqLen > dstlen) {	PORT_SetError(SEC_ERROR_OUTPUT_LEN);	return SECFailure;    }        d = dst;    if (needsQuoting) *d++ = C_DOUBLE_QUOTE;    for (i = 0; i < srclen; i++) {	char c = src[i];	if (c == C_DOUBLE_QUOTE || c == C_BACKSLASH) {	    /* escape it */	    *d++ = C_BACKSLASH;	}	*d++ = c;    }    if (needsQuoting) *d++ = C_DOUBLE_QUOTE;    *d++ = 0;    return SECSuccess;}static SECStatusAppendAVA(char **bufp, unsigned *buflenp, CERTAVA *ava){    char *tagName;    char tmpBuf[384];    unsigned len, maxLen;    int lenLen;    int tag;    SECStatus rv;    SECItem *avaValue = NULL;    tag = CERT_GetAVATag(ava);    switch (tag) {      case SEC_OID_AVA_COUNTRY_NAME:	tagName = "C";	maxLen = 2;	break;      case SEC_OID_AVA_ORGANIZATION_NAME:	tagName = "O";	maxLen = 64;	break;      case SEC_OID_AVA_COMMON_NAME:	tagName = "CN";	maxLen = 64;	break;      case SEC_OID_AVA_LOCALITY:	tagName = "L";	maxLen = 128;	break;      case SEC_OID_AVA_STATE_OR_PROVINCE:	tagName = "ST";	maxLen = 128;	break;      case SEC_OID_AVA_ORGANIZATIONAL_UNIT_NAME:	tagName = "OU";	maxLen = 64;	break;      case SEC_OID_AVA_DC:	tagName = "DC";	maxLen = 128;	break;      case SEC_OID_AVA_DN_QUALIFIER:	tagName = "dnQualifier";	maxLen = 0x7fff;	break;      case SEC_OID_PKCS9_EMAIL_ADDRESS:	tagName = "E";	maxLen = 128;	break;      case SEC_OID_RFC1274_UID:	tagName = "UID";	maxLen = 256;	break;      case SEC_OID_RFC1274_MAIL:	tagName = "MAIL";	maxLen = 256;	break;      default:#if 0	PORT_SetError(SEC_ERROR_INVALID_AVA);	return SECFailure;#else	rv = AppendStr(bufp, buflenp, "ERR=Unknown AVA");	return rv;#endif    }    avaValue = CERT_DecodeAVAValue(&ava->value);    if(!avaValue) {	return SECFailure;    }    /* Check value length */    if ((avaValue->len < 2) || (avaValue->len > maxLen)) {	PORT_SetError(SEC_ERROR_INVALID_AVA);	return SECFailure;    }    len = PORT_Strlen(tagName);    PORT_Memcpy(tmpBuf, tagName, len);    tmpBuf[len++] = '=';        /* escape and quote as necessary */    rv = CERT_RFC1485_EscapeAndQuote(tmpBuf+len, sizeof(tmpBuf)-len, 		    		     (char *)avaValue->data, avaValue->len);    SECITEM_FreeItem(avaValue, PR_TRUE);    if (rv) return SECFailure;        rv = AppendStr(bufp, buflenp, tmpBuf);    return rv;}char *CERT_NameToAscii(CERTName *name){    SECStatus rv;    CERTRDN** rdns;    CERTRDN** lastRdn;    CERTRDN** rdn;    CERTAVA** avas;    CERTAVA* ava;    PRBool first = PR_TRUE;    char *buf = NULL;    unsigned buflen = 0;        rdns = name->rdns;    if (rdns == NULL) {	return NULL;    }        /* find last RDN */    lastRdn = rdns;    while (*lastRdn) lastRdn++;    lastRdn--;        /*     * Loop over name contents in _reverse_ RDN order appending to string     */    for (rdn = lastRdn; rdn >= rdns; rdn--) {	avas = (*rdn)->avas;	while ((ava = *avas++) != NULL) {	    /* Put in comma separator */	    if (!first) {		rv = AppendStr(&buf, &buflen, ", ");		if (rv) goto loser;	    } else {		first = PR_FALSE;	    }	    	    /* Add in tag type plus value into buf */	    rv = AppendAVA(&buf, &buflen, ava);	    if (rv) goto loser;	}    }    return buf;  loser:    PORT_Free(buf);    return NULL;}/* * Return the string representation of a DER encoded distinguished name * "dername" - The DER encoded name to convert */char *CERT_DerNameToAscii(SECItem *dername){    int rv;    PRArenaPool *arena = NULL;    CERTName name;    char *retstr = NULL;        arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);        if ( arena == NULL) {	goto loser;    }        rv = SEC_ASN1DecodeItem(arena, &name, CERT_NameTemplate, dername);        if ( rv != SECSuccess ) {	goto loser;    }    retstr = CERT_NameToAscii(&name);loser:    if ( arena != NULL ) {	PORT_FreeArena(arena, PR_FALSE);    }        return(retstr);}static char *CERT_GetNameElement(CERTName *name, int wantedTag){    CERTRDN** rdns;    CERTRDN *rdn;    CERTAVA** avas;    CERTAVA* ava;    char *buf = 0;    int tag;    SECItem *decodeItem = NULL;        rdns = name->rdns;    while ((rdn = *rdns++) != 0) {	avas = rdn->avas;	while ((ava = *avas++) != 0) {	    tag = CERT_GetAVATag(ava);	    if ( tag == wantedTag ) {		decodeItem = CERT_DecodeAVAValue(&ava->value);		if(!decodeItem) {		    return NULL;		}		buf = (char *)PORT_ZAlloc(decodeItem->len + 1);		if ( buf ) {		    PORT_Memcpy(buf, decodeItem->data, decodeItem->len);		    buf[decodeItem->len] = 0;		}		SECITEM_FreeItem(decodeItem, PR_TRUE);		goto done;	    }	}    }      done:    return buf;}char *CERT_GetCertificateEmailAddress(CERTCertificate *cert){    char *rawEmailAddr = NULL;    char *emailAddr = NULL;    SECItem subAltName;    SECStatus rv;    CERTGeneralName *nameList = NULL;    CERTGeneralName *current;    PRArenaPool *arena = NULL;    int i;        subAltName.data = NULL;    rawEmailAddr = CERT_GetNameElement(&(cert->subject), SEC_OID_PKCS9_EMAIL_ADDRESS);    if ( rawEmailAddr == NULL ) {	rawEmailAddr = CERT_GetNameElement(&(cert->subject), SEC_OID_RFC1274_MAIL);    }    if ( rawEmailAddr == NULL) {	rv = CERT_FindCertExtension(cert,  SEC_OID_X509_SUBJECT_ALT_NAME, &subAltName);	if (rv != SECSuccess) {	    goto finish;	}	arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);	if (!arena) {	    goto finish;	}	nameList = current = CERT_DecodeAltNameExtension(arena, &subAltName);	if (!nameList ) {	    goto finish;	}	if (nameList != NULL) {	    do {		if (current->type == certDirectoryName) {		    rawEmailAddr = CERT_GetNameElement(&(current->name.directoryName), 						       SEC_OID_PKCS9_EMAIL_ADDRESS);		    if ( rawEmailAddr == NULL ) {			rawEmailAddr = CERT_GetNameElement(&(current->name.directoryName), 							   SEC_OID_RFC1274_MAIL);		    }		} else if (current->type == certRFC822Name) {		    rawEmailAddr = (char*)PORT_ZAlloc(current->name.other.len + 1);		    if (!rawEmailAddr) {			goto finish;		    }		    PORT_Memcpy(rawEmailAddr, current->name.other.data, 				current->name.other.len);		    rawEmailAddr[current->name.other.len] = '\0';		}		if (rawEmailAddr) {		    break;		}		current = cert_get_next_general_name(current);	    } while (current != nameList);	}    }    if (rawEmailAddr) {	emailAddr = (char*)PORT_ArenaZAlloc(cert->arena, PORT_Strlen(rawEmailAddr) + 1);	for (i = 0; i <= PORT_Strlen(rawEmailAddr); i++) {	    emailAddr[i] = tolower(rawEmailAddr[i]);	}    } else {	emailAddr = NULL;    }finish:    if ( rawEmailAddr ) {	PORT_Free(rawEmailAddr);    }    /* Don't free nameList, it's part of the arena. */    if (arena) {	PORT_FreeArena(arena, PR_FALSE);    }    if ( subAltName.data ) {	SECITEM_FreeItem(&subAltName, PR_FALSE);    }    return(emailAddr);}char *CERT_GetCertEmailAddress(CERTName *name){    char *rawEmailAddr;    char *emailAddr;        rawEmailAddr = CERT_GetNameElement(name, SEC_OID_PKCS9_EMAIL_ADDRESS);    if ( rawEmailAddr == NULL ) {	rawEmailAddr = CERT_GetNameElement(name, SEC_OID_RFC1274_MAIL);    }    emailAddr = CERT_FixupEmailAddr(rawEmailAddr);    if ( rawEmailAddr ) {	PORT_Free(rawEmailAddr);    }    return(emailAddr);}char *CERT_GetCommonName(CERTName *name){    return(CERT_GetNameElement(name, SEC_OID_AVA_COMMON_NAME));}char *CERT_GetCountryName(CERTName *name){    return(CERT_GetNameElement(name, SEC_OID_AVA_COUNTRY_NAME));}char *CERT_GetLocalityName(CERTName *name){    return(CERT_GetNameElement(name, SEC_OID_AVA_LOCALITY));}char *CERT_GetStateName(CERTName *name){    return(CERT_GetNameElement(name, SEC_OID_AVA_STATE_OR_PROVINCE));}char *CERT_GetOrgName(CERTName *name){    return(CERT_GetNameElement(name, SEC_OID_AVA_ORGANIZATION_NAME));}char *CERT_GetDomainComponentName(CERTName *name){    return(CERT_GetNameElement(name, SEC_OID_AVA_DC));}char *CERT_GetOrgUnitName(CERTName *name){    return(CERT_GetNameElement(name, SEC_OID_AVA_ORGANIZATIONAL_UNIT_NAME));}char *CERT_GetDnQualifier(CERTName *name){    return(CERT_GetNameElement(name, SEC_OID_AVA_DN_QUALIFIER));}char *CERT_GetCertUid(CERTName *name){    return(CERT_GetNameElement(name, SEC_OID_RFC1274_UID));}

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?