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 + -
显示快捷键?