certlist.c

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

C
1,090
字号
        if (trust->sslFlags & CERTDB_VALID_PEER) {            thisUsage = clSSLServer;            goto include;        }                    /* CA certs */        if ((trust->sslFlags & CERTDB_VALID_CA) ||            (trust->emailFlags & CERTDB_VALID_CA) ||            (trust->objectSigningFlags & CERTDB_VALID_CA)) {             thisUsage = clAllCA;            goto include;        }    } /* end of if nickname */    /* Check if this is an email cert that belongs to someone else. */    if (emailAddr && !usercert && (trust->emailFlags & CERTDB_VALID_PEER)) {        /* Someone else's email cert */        thisUsage = clEmailRecipient;        goto include;    }    dontInclude:    *usage = thisUsage;    return PR_FALSE;include:    *usage = thisUsage;    if (state->usage == thisUsage ||        (state->usage == clAllMine &&         (thisUsage == clSSLClient || thisUsage == clEmailSigner))) {                return PR_TRUE;    }    return PR_FALSE;}   /* build/append a cert list string depending on key and usage */SECStatus certlist_get_cert(CERTCertificate *cert, SECItem *dbkey, void *arg){    ssmCLState *state = (ssmCLState *) arg;    SECStatus rv = SECSuccess;    void *certHashKey; /* the key we use to insert into the hash */     ssmCLCertUsage thisUsage;     ssmCertData * data;    char * certInfo = NULL, *nick = NULL;    char * wrapper;        /* check if we want to include cert in our hash table */    if (!certlist_include_cert(cert, state, &thisUsage))        goto done;    /* check if cert is already in the db */    nick = (cert->nickname)?cert->nickname:cert->emailAddr;    if (SSMSortedList_Lookup(*state->hash, nick))        goto done;            /* different wrapper for email certs */    if (thisUsage == clEmailRecipient)        wrapper = state->efmt;    else wrapper = state->fmt;    /* If we get here, then we should include this cert in the hash table. */    rv = (SECStatus)     	(format_raw_cert(cert, wrapper, state->datefmt, &certInfo) == SSM_SUCCESS) ?		SECSuccess : SECFailure;    if (rv != SECSuccess)        goto done;       certHashKey = certlist_get_cert_key(state, cert, thisUsage);        data = (ssmCertData *) PORT_ZAlloc(sizeof(ssmCertData));    data->usage = thisUsage;    data->certEntry = certInfo;    /* XXX the following code is necessary because we want to pick out     *     email signing certs among "my certs"     */    if (cert->trust->emailFlags & CERTDB_USER) {        data->isEmailSigner = PR_TRUE;    }    else {        data->isEmailSigner = PR_FALSE;    }    SSMSortedList_Insert(*state->hash, certHashKey, data);done:    return rv;}static char * escape_quotes(const char * str){    char * outstr = NULL, * ptr = NULL;    int i=0, length = 0;    int quotechar = 0;    if (!str)         goto done;    ptr = str;    while (*ptr) {       length++;       if (*ptr == 39 || *ptr == 34)           quotechar++;       ptr++;    }    outstr = (char *) PORT_ZAlloc(length+quotechar+1);    if (!quotechar) {        memcpy(outstr, str, length);        goto done;    }    ptr = str;    i = 0;    while (i < length+quotechar) {        if (*ptr == 39 || *ptr == 34)             outstr[i++] = 92;        outstr[i++] = *ptr;        ptr++;    }         done:    return outstr;}/* Format a raw cert into (wrapper). */static SSMStatusformat_raw_cert(CERTCertificate *cert, char *wrapper,                void *dfmt, char **result){    char *nickStr = NULL;    char *emailStr = NULL;    char *subjectName = NULL;    char *validStartStr = NULL;    char *validEndStr = NULL;    char * issuerName = NULL;    void *dateFormat = dfmt;    char *isn_ch = NULL;    SSMStatus rv = SSM_SUCCESS;    PR_ASSERT(wrapper);    /* If a date format wasn't supplied, make one. */    if (dateFormat)    {		dateFormat = nlsNewDateFormat();		if (!dateFormat) {			goto loser;		}    }    /* Get the key from the cert in b64 format */    rv = ssm_certlist_get_b64_cert_key(cert, &isn_ch);    if (rv != SSM_SUCCESS)	goto loser;    PR_ASSERT(isn_ch);    nickStr  = (cert->nickname)  ?escape_quotes(cert->nickname):PL_strdup("-");    emailStr = (cert->emailAddr) ?escape_quotes(cert->emailAddr):PL_strdup("-");    subjectName =  (cert->subjectName) ? escape_quotes(cert->subjectName) :         PL_strdup("-");    issuerName = CERT_GetOrgName(&cert->issuer);    issuerName = issuerName ? escape_quotes(issuerName) : PL_strdup("-");            validStartStr = DER_UTCDayToAscii(&cert->validity.notBefore);    if (!validStartStr)         validStartStr = PL_strdup("");    validEndStr = DER_UTCDayToAscii(&cert->validity.notAfter);    if (!validEndStr)         validEndStr = PL_strdup("");    SSMTextGen_UTF8StringClear(result);    *result = PR_smprintf(wrapper, isn_ch, nickStr, emailStr, subjectName,                           validStartStr, validEndStr,                          issuerName, 0);    SSM_DebugUTF8String("wrapped cert", *result);    goto done; loser:    SSM_DEBUG("Couldn't format cert!");    if (rv == SSM_SUCCESS)        rv = SSM_FAILURE; done:    PR_FREEIF(nickStr);    PR_FREEIF(emailStr);    PR_FREEIF(subjectName);    PR_FREEIF(issuerName);    PR_FREEIF(isn_ch);    PR_FREEIF(validStartStr);    PR_FREEIF(validEndStr);    if (dateFormat && !dfmt) /* if we made the date format, delete it */        nlsFreeDateFormat(dateFormat);    return rv;}/* Enumerator for cert hash entries. Embed cert information in   the wrapper (state->wrapper). */SSMStatus certlist_display_cert(PRIntn index, void * arg, void * key, void * itemdata){    ssmCLState *state = (ssmCLState *) arg;    SSMStatus rv = SSM_SUCCESS;    ssmCertData * data = (ssmCertData *) itemdata;         if (state->usage == data->usage ||        (state->usage == clAllMine &&          (data->usage == clSSLClient || data->usage == clEmailSigner)) ||        (state->usage == clEmailSigner && data->usage == clAllMine &&         data->isEmailSigner)) {         rv = SSM_ConcatenateUTF8String(&state->output, data->certEntry);        if (rv != SSM_SUCCESS)            goto loser;    }    goto done;loser:    SSM_DEBUG("certlist_display_cert: couldn't add cert info to display list!");done:    /* keep going */    return SSM_SUCCESS;}    /* get the certType parameter */SSMStatuscertlist_get_usage(ssmCLState *state){    char *usageStr = (char *) SSM_At(state->cx->m_params, CERTLIST_PARAM_USAGE);    SSMStatus rv = SSM_SUCCESS;    PR_ASSERT(usageStr);    if (!usageStr)    {        SSM_HTTPReportSpecificError(state->cx->m_request,                                     "certlist_get_usage: "                                    "usage parameter is NULL");        goto loser;    }    /* Figure out which one it is. */    if (!MIN_STRCMP(usageStr, "AllMine"))        state->usage = clAllMine;    else if (!MIN_STRCMP(usageStr, "SSLC"))        state->usage = clSSLClient;    else if (!MIN_STRCMP(usageStr, "EmailS"))        state->usage = clEmailSigner;    else if (!MIN_STRCMP(usageStr, "SSLS"))        state->usage = clSSLServer;    else if (!MIN_STRCMP(usageStr, "EmailR"))        state->usage = clEmailRecipient;    else if (!MIN_STRCMP(usageStr, "CA"))        state->usage = clAllCA;    else /* bad value */    {        SSM_HTTPReportSpecificError(state->cx->m_request,                                    "_certList: Bad usage -- must be "                                    "AllMine|SSLClient|EmailSigner|"                                    "SSLServer|EmailRecipient|CA");        goto loser;    }    goto done;loser:    if (rv == SSM_SUCCESS) rv = SSM_FAILURE;done:    return rv;}/* get the certType parameter */SSMStatuscertlist_get_key_type(ssmCLState *state){    char *keyStr = (char *) SSM_At(state->cx->m_params, CERTLIST_PARAM_KEY);    SSMStatus rv = SSM_SUCCESS;    PR_ASSERT(keyStr);    if (!keyStr)    {        SSM_HTTPReportSpecificError(state->cx->m_request,                                     "certlist_get_key_type: "                                    "key parameter is NULL");        goto loser;    }    /* Figure out which one it is. */    if (!MIN_STRCMP(keyStr, "nick"))        state->key = clNick;    else if (!MIN_STRCMP(keyStr, "certID"))        state->key = clCertID;    else if ((!MIN_STRCMP(keyStr, "rid"))             ||(!MIN_STRCMP(keyStr, "RID")))        state->key = clRID;    else if (!MIN_STRCMP(keyStr, "email"))        state->key = clEmail;    else/* bad value */    {        SSM_HTTPReportSpecificError(state->cx->m_request,                                     "_certList: Bad cert key -- must be "                                    "nick|certID|RID");        goto loser;    }    goto done;loser:    if (rv == SSM_SUCCESS) rv = SSM_FAILURE;done:    return rv;}SSMStatusssm_populate_key_hash(ssmCLState * state){    SSMCompare_fn  keyComparer = NULL;    SSMListFree_fn keyFree = NULL;    SSMListFree_fn dataFree = certlist_free_data;    SECStatus srv;    SSMStatus rv = SSM_SUCCESS;    char *tempUStr = NULL;    PermCertCallback callback = certlist_get_cert;    /* Based on the usage, choose hasher/key comparer functions for       the hash table we create below. */    switch(state->key)        {        case clRID:            keyComparer = certlist_rid_compare;            keyFree = certlist_none;            break;        case clEmail:        case clCertID:        case clNick:            keyComparer = certlist_compare_strings;            keyFree = certlist_free_string;            break;        default:            PR_ASSERT(0);         }    list_functions.keyCompare = keyComparer;    list_functions.freeListItemData = dataFree;    list_functions.freeListItemKey = keyFree;    /* Create the hash table if needed */    if (!*state->hash)        *state->hash = SSMSortedList_New(&list_functions);    if (!*state->hash)         goto loser;    PR_ASSERT(state->db);        /* Get the wrapper text. */    rv = SSM_GetAndExpandTextKeyedByString(state->cx, WRAPPER, &tempUStr);    if (rv != SSM_SUCCESS)        goto loser; /* error string set by the called function */    SSM_DebugUTF8String("Certlist wrapper", tempUStr);    state->fmt = tempUStr;    tempUStr = NULL;    /* wrapper for email certs */    rv = SSM_GetAndExpandTextKeyedByString(state->cx, EMAIL_WRAPPER, &tempUStr);    if (rv != SSM_SUCCESS)        goto loser; /* error string set by the called function */    SSM_DebugUTF8String("Certlist email wrapper", tempUStr);    state->efmt = tempUStr;    tempUStr = NULL;    /*        Create a DateFormat object which we will use to convert       cert date/times into displayable text.     */	state->datefmt = nlsNewDateFormat();

⌨️ 快捷键说明

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