📄 certlist.c
字号:
/* -*- 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"enum{ CERTLIST_PARAM_KEY = (PRIntn) 0, CERTLIST_PARAM_USAGE, CERTLIST_PARAM_PREFIX, /* CERTLIST_PARAM_WRAPPER, 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; CERTCertDBHandle * db; SSMSortedList **hash; /* Hash to contain list of certs to display */ ssmCLCertKey key; ssmCLCertUsage usage;} ssmCLState;static SSMStatus format_raw_cert();/* 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; /* 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 */ 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;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -