certhigh.c

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

C
1,101
字号
    /* allocate the header structure */    names = (CERTDistNames *)PORT_ArenaAlloc(arena, sizeof(CERTDistNames));    if ( names == NULL ) {	goto loser;    }    /* initialize the header struct */    names->arena = arena;    names->head = NULL;    names->nnames = 0;    names->names = NULL;        /* collect the names from the database */    rv = SEC_TraversePermCerts(handle, CollectDistNames, (void *)names);    if ( rv ) {	goto loser;    }    /* construct the array from the list */    if ( names->nnames ) {	names->names = (SECItem*)PORT_ArenaAlloc(arena, names->nnames * sizeof(SECItem));	if ( names->names == NULL ) {	    goto loser;	}    	node = (dnameNode *)names->head;		for ( i = 0; i < names->nnames; i++ ) {	    PORT_Assert(node != NULL);	    	    names->names[i] = node->name;	    node = node->next;	}	PORT_Assert(node == NULL);    }    return(names);    loser:    PORT_FreeArena(arena, PR_FALSE);    return(NULL);}CERTDistNames *CERT_DistNamesFromNicknames(CERTCertDBHandle *handle, char **nicknames,			   int nnames){    CERTDistNames *dnames = NULL;    PRArenaPool *arena;    int i, rv;    SECItem *names = NULL;    CERTCertificate *cert = NULL;        arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);    if (arena == NULL) goto loser;    dnames = (CERTDistNames*)PORT_Alloc(sizeof(CERTDistNames));    if (dnames == NULL) goto loser;    dnames->arena = arena;    dnames->nnames = nnames;    dnames->names = names = (SECItem*)PORT_Alloc(nnames * sizeof(SECItem));    if (names == NULL) goto loser;        for (i = 0; i < nnames; i++) {	cert = CERT_FindCertByNicknameOrEmailAddr(handle, nicknames[i]);	if (cert == NULL) goto loser;	rv = SECITEM_CopyItem(arena, &names[i], &cert->derSubject);	if (rv == SECFailure) goto loser;	CERT_DestroyCertificate(cert);    }    return dnames;    loser:    if (cert != NULL)	CERT_DestroyCertificate(cert);    if (arena != NULL)	PORT_FreeArena(arena, PR_FALSE);    return NULL;}/* [ from pcertdb.c - calls Ascii to Name ] *//* * Lookup a certificate in the database by name */CERTCertificate *CERT_FindCertByNameString(CERTCertDBHandle *handle, char *nameStr){    CERTName *name;    SECItem *nameItem;    CERTCertificate *cert = NULL;    PRArenaPool *arena = NULL;        arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);        if ( arena == NULL ) {	goto loser;    }        name = CERT_AsciiToName(nameStr);        if ( name ) {	nameItem = SEC_ASN1EncodeItem (arena, NULL, (void *)name,				       CERT_NameTemplate);	if ( nameItem == NULL ) {	    goto loser;	}	cert = CERT_FindCertByName(handle, nameItem);	CERT_DestroyName(name);    }loser:    if ( arena ) {	PORT_FreeArena(arena, PR_FALSE);    }        return(cert);}/* From certv3.c */CERTCrlDistributionPoints *CERT_FindCRLDistributionPoints (CERTCertificate *cert){    SECItem encodedExtenValue;    SECStatus rv;    encodedExtenValue.data = NULL;    encodedExtenValue.len = 0;    rv = cert_FindExtension(cert->extensions, SEC_OID_X509_CRL_DIST_POINTS,			    &encodedExtenValue);    if ( rv != SECSuccess ) {	return (NULL);    }    return (CERT_DecodeCRLDistributionPoints (cert->arena,					      &encodedExtenValue));}/* From crl.c */CERTSignedCrl * CERT_ImportCRL   (CERTCertDBHandle *handle, SECItem *derCRL, char *url, int type, void *wincx){    CERTCertificate *caCert;    CERTSignedCrl *newCrl, *crl;    SECStatus rv;    newCrl = crl = NULL;    PORT_Assert (handle != NULL);    do {	newCrl = CERT_DecodeDERCrl(NULL, derCRL, type);	if (newCrl == NULL) {	    if (type == SEC_CRL_TYPE) {		/* only promote error when the error code is too generic */		if (PORT_GetError () == SEC_ERROR_BAD_DER)			PORT_SetError(SEC_ERROR_CRL_INVALID);	    } else {		PORT_SetError(SEC_ERROR_KRL_INVALID);	    }	    break;			}    	caCert = CERT_FindCertByName (handle, &newCrl->crl.derName);	if (caCert == NULL) {	    PORT_SetError(SEC_ERROR_UNKNOWN_ISSUER);	    	    break;	}	/* If caCert is a v3 certificate, make sure that it can be used for	   crl signing purpose */	rv = CERT_CheckCertUsage (caCert, KU_CRL_SIGN);	if (rv != SECSuccess) {	    break;	}	rv = CERT_VerifySignedData(&newCrl->signatureWrap, caCert,				   PR_Now(), wincx);	if (rv != SECSuccess) {	    if (type == SEC_CRL_TYPE) {		PORT_SetError(SEC_ERROR_CRL_BAD_SIGNATURE);	    } else {		PORT_SetError(SEC_ERROR_KRL_BAD_SIGNATURE);	    }	    break;	}	/* Do CRL validation and add to the dbase if this crl is more present then the one	   in the dbase, if one exists.	 */	crl = cert_DBInsertCRL (handle, url, newCrl, derCRL, type);    } while (0);    SEC_DestroyCrl (newCrl);    return (crl);}/* From certdb.c */SECStatusCERT_ImportCAChain(SECItem *certs, int numcerts, SECCertUsage certUsage){    SECStatus rv;    SECItem *derCert;    SECItem certKey;    PRArenaPool *arena;    CERTCertificate *cert = NULL;    CERTCertificate *newcert = NULL;    CERTCertDBHandle *handle;    CERTCertTrust trust;    PRBool isca;    char *nickname;    unsigned int certtype;        handle = CERT_GetDefaultCertDB();        arena = NULL;    arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);    if ( ! arena ) {	goto loser;    }    while (numcerts--) {	derCert = certs;	certs++;		/* get the key (issuer+cn) from the cert */	rv = CERT_KeyFromDERCert(arena, derCert, &certKey);	if ( rv != SECSuccess ) {	    goto loser;	}	/* same cert already exists in the database, don't need to do	 * anything more with it	 */	cert = CERT_FindCertByKey(handle, &certKey);	if ( cert ) {	    CERT_DestroyCertificate(cert);	    cert = NULL;	    continue;	}	/* decode my certificate */	newcert = CERT_DecodeDERCertificate(derCert, PR_FALSE, NULL);	if ( newcert == NULL ) {	    goto loser;	}	/* make sure that cert is valid */	rv = CERT_CertTimesValid(newcert);	if ( rv == SECFailure ) {	    goto endloop;	}	/* does it have the CA extension */		/*	 * Make sure that if this is an intermediate CA in the chain that	 * it was given permission by its signer to be a CA.	 */	isca = CERT_IsCACert(newcert, &certtype);	if ( !isca ) {	    goto endloop;	}	/* SSL ca's must have the ssl bit set */	if ( ( certUsage == certUsageSSLCA ) &&	    ( ( certtype & NS_CERT_TYPE_SSL_CA ) != NS_CERT_TYPE_SSL_CA ) ) {	    goto endloop;	}	/* it passed all of the tests, so lets add it to the database */	/* mark it as a CA */	PORT_Memset((void *)&trust, 0, sizeof(trust));	switch ( certUsage ) {	  case certUsageSSLCA:	    trust.sslFlags = CERTDB_VALID_CA;	    break;	  case certUsageUserCertImport:	    if ( ( certtype & NS_CERT_TYPE_SSL_CA ) == NS_CERT_TYPE_SSL_CA ) {		trust.sslFlags = CERTDB_VALID_CA;	    }	    if ( ( certtype & NS_CERT_TYPE_EMAIL_CA ) ==		NS_CERT_TYPE_EMAIL_CA ) {		trust.emailFlags = CERTDB_VALID_CA;	    }	    if ( ( certtype & NS_CERT_TYPE_OBJECT_SIGNING_CA ) ==		NS_CERT_TYPE_OBJECT_SIGNING_CA ) {		trust.objectSigningFlags = CERTDB_VALID_CA;	    }	    break;	  default:	    PORT_Assert(0);	    break;	}		cert = CERT_NewTempCertificate(handle, derCert, NULL, PR_FALSE, PR_TRUE);	if ( cert == NULL ) {	    goto loser;	}		/* get a default nickname for it */	nickname = CERT_MakeCANickname(cert);	rv = CERT_AddTempCertToPerm(cert, nickname, &trust);	/* free the nickname */	if ( nickname ) {	    PORT_Free(nickname);	}	CERT_DestroyCertificate(cert);	cert = NULL;		if ( rv != SECSuccess ) {	    goto loser;	}endloop:	if ( newcert ) {	    CERT_DestroyCertificate(newcert);	    newcert = NULL;	}	    }    rv = SECSuccess;    goto done;loser:    rv = SECFailure;done:        if ( newcert ) {	CERT_DestroyCertificate(newcert);	newcert = NULL;    }        if ( cert ) {	CERT_DestroyCertificate(cert);	cert = NULL;    }        if ( arena ) {	PORT_FreeArena(arena, PR_FALSE);    }    return(rv);}/* Moved from certdb.c *//*** CERT_CertChainFromCert**** Construct a CERTCertificateList consisting of the given certificate and all** of the issuer certs until we either get to a self-signed cert or can't find** an issuer.  Since we don't know how many certs are in the chain we have to** build a linked list first as we count them.*/typedef struct certNode {    struct certNode *next;    CERTCertificate *cert;} certNode;CERTCertificateList *CERT_CertChainFromCert(CERTCertificate *cert, SECCertUsage usage,		       PRBool includeRoot){    CERTCertificateList *chain = NULL;    CERTCertificate *c;    SECItem *p;    int rv, len = 0;    PRArenaPool *tmpArena, *arena;    certNode *head, *tail, *node;    /*     * Initialize stuff so we can goto loser.     */    head = NULL;    arena = NULL;    /* arena for linked list */    tmpArena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);    if (tmpArena == NULL) goto no_memory;    /* arena for SecCertificateList */    arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);    if (arena == NULL) goto no_memory;    head = tail = (certNode*)PORT_ArenaZAlloc(tmpArena, sizeof(certNode));    if (head == NULL) goto no_memory;    /* put primary cert first in the linked list */    head->cert = c = CERT_DupCertificate(cert);    if (head->cert == NULL) goto loser;    len++;    /* add certs until we come to a self-signed one */    while(SECITEM_CompareItem(&c->derIssuer, &c->derSubject) != SECEqual) {	c = CERT_FindCertIssuer(tail->cert, PR_Now(), usage);	if (c == NULL) {	    /* no root is found, so make sure we don't attempt to delete one	     * below	     */	    includeRoot = PR_TRUE;	    break;	}		tail->next = (certNode*)PORT_ArenaZAlloc(tmpArena, sizeof(certNode));	tail = tail->next;	if (tail == NULL) goto no_memory;		tail->cert = c;	len++;    }    /* now build the CERTCertificateList */    chain = (CERTCertificateList *)PORT_ArenaAlloc(arena, sizeof(CERTCertificateList));    if (chain == NULL) goto no_memory;    chain->certs = (SECItem*)PORT_ArenaAlloc(arena, len * sizeof(SECItem));    if (chain->certs == NULL) goto no_memory;        for(node = head, p = chain->certs; node; node = node->next, p++) {	rv = SECITEM_CopyItem(arena, p, &node->cert->derCert);	CERT_DestroyCertificate(node->cert);	node->cert = NULL;	if (rv < 0) goto loser;    }    if ( !includeRoot && len > 1) {	chain->len = len - 1;    } else {	chain->len = len;    }        chain->arena = arena;    PORT_FreeArena(tmpArena, PR_FALSE);        return chain;no_memory:    PORT_SetError(SEC_ERROR_NO_MEMORY);loser:    if (head != NULL) {	for (node = head; node; node = node->next) {	    if (node->cert != NULL)		CERT_DestroyCertificate(node->cert);	}    }    if (arena != NULL) {	PORT_FreeArena(arena, PR_FALSE);    }    if (tmpArena != NULL) {	PORT_FreeArena(tmpArena, PR_FALSE);    }    return NULL;}/* Builds a CERTCertificateList holding just one DER-encoded cert, namely** the one for the cert passed as an argument.*/CERTCertificateList *CERT_CertListFromCert(CERTCertificate *cert){    CERTCertificateList *chain = NULL;    int rv;    PRArenaPool *arena;    /* arena for SecCertificateList */    arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);    if (arena == NULL) goto no_memory;    /* build the CERTCertificateList */    chain = (CERTCertificateList *)PORT_ArenaAlloc(arena, sizeof(CERTCertificateList));    if (chain == NULL) goto no_memory;    chain->certs = (SECItem*)PORT_ArenaAlloc(arena, 1 * sizeof(SECItem));    if (chain->certs == NULL) goto no_memory;    rv = SECITEM_CopyItem(arena, chain->certs, &(cert->derCert));    if (rv < 0) goto loser;    chain->len = 1;    chain->arena = arena;    return chain;no_memory:    PORT_SetError(SEC_ERROR_NO_MEMORY);loser:    if (arena != NULL) {	PORT_FreeArena(arena, PR_FALSE);    }    return NULL;}CERTCertificateList *CERT_DupCertList(CERTCertificateList * oldList){    CERTCertificateList *newList = NULL;    PRArenaPool         *arena   = NULL;    SECItem             *newItem;    SECItem             *oldItem;    int                 len      = oldList->len;    int                 rv;    /* arena for SecCertificateList */    arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);    if (arena == NULL) 	goto no_memory;    /* now build the CERTCertificateList */    newList = PORT_ArenaNew(arena, CERTCertificateList);    if (newList == NULL) 	goto no_memory;    newList->arena = arena;    newItem = (SECItem*)PORT_ArenaAlloc(arena, len * sizeof(SECItem));    if (newItem == NULL) 	goto no_memory;    newList->certs = newItem;    newList->len   = len;    for (oldItem = oldList->certs; len > 0; --len, ++newItem, ++oldItem) {	rv = SECITEM_CopyItem(arena, newItem, oldItem);	if (rv < 0) 	    goto loser;    }    return newList;no_memory:    PORT_SetError(SEC_ERROR_NO_MEMORY);loser:    if (arena != NULL) {	PORT_FreeArena(arena, PR_FALSE);    }    return NULL;}voidCERT_DestroyCertificateList(CERTCertificateList *list){    PORT_FreeArena(list->arena, PR_FALSE);}

⌨️ 快捷键说明

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