certlist.c

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

C
1,090
字号
/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- *//* * The contents of this file are subject to the Mozilla Public * License Version 1.1 (the "License"); you may not use this file * except in compliance with the License. You may obtain a copy of * the License at http://www.mozilla.org/MPL/ *  * Software distributed under the License is distributed on an "AS * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or * implied. See the License for the specific language governing * rights and limitations under the License. *  * The Original Code is the Netscape security libraries. *  * The Initial Developer of the Original Code is Netscape * Communications Corporation.  Portions created by Netscape are  * Copyright (C) 1994-2000 Netscape Communications Corporation.  All * Rights Reserved. *  * Contributor(s): *  * Alternatively, the contents of this file may be used under the * terms of the GNU General Public License Version 2 or later (the * "GPL"), in which case the provisions of the GPL are applicable  * instead of those above.  If you wish to allow use of your  * version of this file only under the terms of the GPL and not to * allow others to use your version of this file under the MPL, * indicate your decision by deleting the provisions above and * replace them with the notice and other provisions required by * the GPL.  If you do not delete the provisions above, a recipient * may use your version of this file under either the MPL or the * GPL. */#include "certlist.h"#include "nlsutil.h"#include "base64.h"#include "cert.h"#include "certdb.h"#include "textgen.h"#include "minihttp.h"#include "advisor.h"#include "slist.h"#include "nspr.h"#include "nlslayer.h"enum{    CERTLIST_PARAM_KEY = (PRIntn) 0,    CERTLIST_PARAM_USAGE,    CERTLIST_PARAM_PREFIX,    /* CERTLIST_PARAM_WRAPPER,  -jp not used, as we format all certs together */    CERTLIST_PARAM_SUFFIX,    CERTLIST_PARAM_COUNT};SSMSortedListFn list_functions;#define WRAPPER "cert_list_item"#define EMAIL_WRAPPER "cert_list_email_item"typedef enum{    clNick,    clCertID, /* issuer and serial number */    clRID,    clEmail} ssmCLCertKey;typedef struct {    SSMTextGenContext *cx;    char *output;    char *temp;    char *fmt;    char *efmt;    void *datefmt;    CERTCertDBHandle * db;    SSMSortedList **hash; /* Hash to contain list of certs to display */    ssmCLCertKey key;    ssmCLCertUsage usage;} ssmCLState;static SSMStatus format_raw_cert(CERTCertificate *cert, char *wrapper,                                 void*dfmt, char **result);/* Hash table functions */PRIntn ssm_certhash_rid_compare(const void *v1, const void *v2);PLHashNumber ssm_certhash_issuersn_hash(const void *v);PRIntn ssm_certhash_issuersn_compare(const void *v1, const void *v2);PRIntn ssm_pointer_compare(const void *v1, const void *v2);PRIntn ssm_certhash_cert_compare(const void *v1, const void *v2);void * ssm_certhash_alloc_table(void *state, PRSize size);void ssm_certhash_free_table(void *state, void *item);PLHashEntry * ssm_certhash_alloc_entry(void *state, const void *key);void ssm_certhash_free_entry(void *s, PLHashEntry *he, PRUintn flag);void certlist_free_item(SECItem *item);void certlist_dereturnify(char *s);SSMStatus ssm_certlist_get_b64_cert_key(CERTCertificate *cert, char **result);void * certlist_get_cert_key(ssmCLState *state, CERTCertificate *cert, ssmCLCertUsage usage);PRBool certlist_include_cert(CERTCertificate * cert, ssmCLState *state,                       ssmCLCertUsage * usage);SECStatus certlist_get_cert(CERTCertificate *cert, SECItem *dbkey, void *arg);SSMStatus certlist_display_cert(PRIntn index, void * arg,                                 void * key, void * itemdata);PRIntn certlist_wrap_cert(PLHashEntry *he, PRIntn index, void *arg);SSMStatus certlist_get_usage(ssmCLState *state);SSMStatus certlist_get_key_type(ssmCLState *state);SSMStatus ssm_populate_key_hash(ssmCLState * state);PRIntncertlist_rid_compare(const void *v1, const void *v2){  SSMResourceID rid1 = (SSMResourceID) v1;    SSMResourceID rid2 = (SSMResourceID) v2;    PRIntn rv;    if (rid1 < rid2)	rv = -1;    else if (rid1 > rid2)	rv = 1;    else	rv = 0;    return rv;}PRIntn certlist_compare_strings(const void * v1, const void *v2){    return PL_strcasecmp((char *)v1, (char *)v2);}PRIntn certlist_issuersn_compare(const void *v1, const void *v2){     PRIntn rv;    SECComparison cmp = SECLessThan; /* this is arbitrary */    const CERTIssuerAndSN *i1 = (const CERTIssuerAndSN *) v1;    const CERTIssuerAndSN *i2 = (const CERTIssuerAndSN *) v2;    PR_ASSERT(i1);    PR_ASSERT(i2);    if (!i1 || !i2)	goto loser;    cmp = SECITEM_CompareItem(&(i1->derIssuer), &(i2->derIssuer));    if (cmp == SECEqual)	cmp = SECITEM_CompareItem(&(i2->serialNumber), &(i2->serialNumber)); loser:    /* Don't need to free i1 and i2, since they are allocated out of       the certs' arenas. They will be freed when the certs are freed. */    rv = (PRIntn) cmp;    return rv;}/* Free ops for cert list */voidcertlist_free_data(void * data){    /* Free the cert, then (if asked) free the entry. */    PR_Free(((ssmCertData *)data)->certEntry);    PR_Free((ssmCertData *)data);}void certlist_none(void * data){    return;}void certlist_free_string(void * key){    PR_Free((char *)key);}/* Utility routines for cert list keyword handler below */voidcertlist_free_item(SECItem *item){    if (item)    {	if (item->data)	    PR_Free(item->data);	PR_Free(item);    }}voidcertlist_dereturnify(char *s){    char *c = s;    while(*c)    {        if ((*c == '\015') || (*c == '\012'))        {            char *c2 = c;            while ((*c2 == '\015') || (*c2 == '\012'))                c2++;            /* move the rest of the string on top of c */            memmove(c, c2, strlen(c2));        }	c++;    }}SSMStatusssm_certlist_get_b64_cert_key(CERTCertificate *cert, char **result){    SECItem *certKeyItem;    CERTIssuerAndSN *isn = NULL;    SSMStatus rv = SSM_SUCCESS;    PR_ASSERT(cert && result);    *result = NULL; /* in case we fail */    isn = CERT_GetCertIssuerAndSN(NULL, cert);    if (!isn)	goto loser;    certKeyItem = (SECItem *) PR_CALLOC(sizeof(SECItem));    if (!certKeyItem)	goto loser;    certKeyItem->len = isn->serialNumber.len + isn->derIssuer.len;    certKeyItem->data = (unsigned char*)PR_CALLOC(certKeyItem->len);    if (certKeyItem->data == NULL)	goto loser;    /* copy the serialNumber */    memcpy(certKeyItem->data, isn->serialNumber.data,	   isn->serialNumber.len);    /* copy the issuer */    memcpy( &(certKeyItem->data[isn->serialNumber.len]),	    isn->derIssuer.data, isn->derIssuer.len);    /* b64 the item */    *result = BTOA_ConvertItemToAscii(certKeyItem);    certlist_dereturnify(*result);    goto done; loser:    rv = SSM_FAILURE; done:    certlist_free_item(certKeyItem);    return rv;}/* get the appropriate key depending on what key type we have chosen. */void *certlist_get_cert_key(ssmCLState *state, CERTCertificate *cert, ssmCLCertUsage usage){    char *result_ch = NULL;    void *result = NULL;    SSMStatus rv = SSM_SUCCESS;    PR_ASSERT(cert);    if (!cert)         return result;    switch(state->key)    {    case clCertID:	rv = ssm_certlist_get_b64_cert_key(cert, &result_ch);	PR_ASSERT(rv == SSM_SUCCESS);	result = result_ch;	break;    case clRID:	PR_ASSERT(!"Not yet implemented.");	break;    case clNick:        /* duplicate the nickname */        if (usage == clEmailRecipient) {            PR_ASSERT(cert && cert->emailAddr);            result = PR_CALLOC(strlen(cert->emailAddr)+1);            if (result)                PL_strcpy((char*)result, cert->emailAddr);        } else {            PR_ASSERT(cert && cert->nickname);            result = PR_CALLOC(strlen(cert->nickname)+1);            if (result)                PL_strcpy((char *) result, cert->nickname);        }        break;       case clEmail:        PR_ASSERT(cert && cert->emailAddr);        result = PR_CALLOC(strlen(cert->emailAddr)+1);        if (result)            PL_strcpy((char*)result, cert->emailAddr);        break;    default:        PR_ASSERT(0); /* scream if we defaulted here */    }    return result;}PRBoolcertlist_include_cert(CERTCertificate * cert, ssmCLState *state,                       ssmCLCertUsage * usage){    PRBool usercert = PR_FALSE;    char *nickname;    char *emailAddr;    CERTCertTrust *trust;    ssmCLCertUsage thisUsage = clNoUsage;    /* jsw said: look at the base cert info stuff, not the dbEntry since     * we may have been called from a PKCS#11 module */    nickname = cert->nickname;    trust = cert->trust;    emailAddr = cert->emailAddr;    /* Don't display certs that are invisible */    if ( ( ( trust->sslFlags & CERTDB_INVISIBLE_CA ) ||           (trust->emailFlags & CERTDB_INVISIBLE_CA ) ||           (trust->objectSigningFlags & CERTDB_INVISIBLE_CA ) ) )         goto dontInclude;        if (nickname) {        /*            it's a cert I have named. Could be a personal cert of mine,           an SSL server cert, or a CA cert. Find out what kind.        */        if (state->usage == clSSLClient) {            if (trust->sslFlags & CERTDB_USER) {                /* It's an SSL cert I own. */                thisUsage = clSSLClient;                goto include;            }            else {                goto dontInclude;            }        }        if (state->usage == clEmailSigner) {            if (trust->emailFlags & CERTDB_USER) {                /* It's an email cert I own. */                thisUsage = clEmailSigner;                goto include;            }            else {                goto dontInclude;            }        }        if (state->usage == clAllMine) {            if ((trust->sslFlags & CERTDB_USER) ||                (trust->emailFlags & CERTDB_USER) ||                (trust->objectSigningFlags & CERTDB_USER)) {                /* It's a cert I own. */                usercert = PR_TRUE;                thisUsage = clAllMine;                goto include;            }            else {                goto dontInclude;            }        }                    /* it is an SSL site */

⌨️ 快捷键说明

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