jarver.c
来自「支持SSL v2/v3, TLS, PKCS #5, PKCS #7, PKCS」· C语言 代码 · 共 2,030 行 · 第 1/3 页
C
2,030 行
/* Try the CN plus O */ cert_o = CERT_GetOrgName (&cert->subject); cn_o_length = PORT_Strlen (cert_cn) + 3 + PORT_Strlen (cert_o) + 20; cert_cn_o = (char*)PORT_ZAlloc (cn_o_length); PR_snprintf (cert_cn_o, cn_o_length, "%s's %s Certificate", cert_cn, cert_o);#ifdef USE_MOZ_THREAD if (jar_moz_nickname (CERT_GetDefaultCertDB(), cert_cn_o) == NULL)#else if (CERT_FindCertByNickname (CERT_GetDefaultCertDB(), cert_cn_o) == NULL)#endif return cert_cn; } /* If all that failed, use the ugly nickname */ return cert->nickname ? PORT_Strdup (cert->nickname) : NULL; }/* * J A R _ c e r t _ h t m l * * Return an HTML representation of the certificate * designated by the given fingerprint, in specified style. * * JAR is optional, but supply it if you can in order * to optimize. * */char *JAR_cert_html (JAR *jar, int style, long keylen, void *key, int *result) { char *html; CERTCertificate *cert; *result = -1; if (style != 0) return NULL; cert = jar_get_certificate (jar, keylen, key, result); if (cert == NULL || *result < 0) return NULL; *result = 0; html = CERT_HTMLCertInfo (cert, /* show images */ PR_TRUE, /*show issuer*/PR_TRUE); if (html == NULL) *result = -1; return html; }/* * J A R _ s t a s h _ c e r t * * Stash the certificate pointed to by this * fingerprint, in persistent storage somewhere. * */extern int PR_CALLBACK JAR_stash_cert (JAR *jar, long keylen, void *key) { int result = 0; char *nickname; CERTCertTrust trust; CERTCertDBHandle *certdb; CERTCertificate *cert, *newcert; cert = jar_get_certificate (jar, keylen, key, &result); if (result < 0) return result; if (cert == NULL) return JAR_ERR_GENERAL; if ((certdb = JAR_open_database()) == NULL) return JAR_ERR_GENERAL; /* Attempt to give a name to the newish certificate */ nickname = jar_choose_nickname (cert);#ifdef USE_MOZ_THREAD newcert = jar_moz_nickname (certdb, nickname);#else newcert = CERT_FindCertByNickname (certdb, nickname);#endif if (newcert && newcert->isperm) { /* already in permanant database */ return 0; } if (newcert) cert = newcert; /* FIX, since FindCert returns a bogus dbhandle set it ourselves */ cert->dbhandle = certdb;#if 0 nickname = cert->subjectName; if (nickname) { /* Not checking for a conflict here. But this should be a new cert or it would have been found earlier. */ nickname = jar_cert_element (nickname, "CN=", 1); if (SEC_CertNicknameConflict (nickname, cert->dbhandle)) { /* conflict */ nickname = PORT_Realloc (&nickname, PORT_Strlen (nickname) + 3); /* Beyond one copy, there are probably serious problems so we will stop at two rather than counting.. */ PORT_Strcat (nickname, " #2"); } }#endif if (nickname != NULL) { PORT_Memset ((void *) &trust, 0, sizeof(trust));#ifdef USE_MOZ_THREAD if (jar_moz_perm (cert, nickname, &trust) != SECSuccess) #else if (CERT_AddTempCertToPerm (cert, nickname, &trust) != SECSuccess) #endif { /* XXX might want to call PORT_GetError here */ result = JAR_ERR_GENERAL; } } JAR_close_database (certdb); return result; }/* * J A R _ f e t c h _ c e r t * * Given an opaque identifier of a certificate, * return the full certificate. * * The new function, which retrieves by key. * */void *JAR_fetch_cert (long length, void *key) { SECItem seckey; CERTCertificate *cert = NULL; CERTCertDBHandle *certdb; certdb = JAR_open_database(); if (certdb) { seckey.len = length; seckey.data = (unsigned char*)key;#ifdef USE_MOZ_THREAD cert = jar_moz_certkey (certdb, &seckey);#else cert = CERT_FindCertByKey (certdb, &seckey);#endif JAR_close_database (certdb); } return (void *) cert; }/* * j a r _ g e t _ m f _ d i g e s t * * Retrieve a corresponding saved digest over a section * of the main manifest file. * */static JAR_Digest *jar_get_mf_digest (JAR *jar, char *pathname) { JAR_Item *it; JAR_Digest *dig; ZZLink *link; ZZList *list; list = jar->manifest; if (ZZ_ListEmpty (list)) return NULL; for (link = ZZ_ListHead (list); !ZZ_ListIterDone (list, link); link = link->next) { it = link->thing; if (it->type == jarTypeSect && it->pathname && !PORT_Strcmp (it->pathname, pathname)) { dig = (JAR_Digest *) it->data; return dig; } } return NULL; }/* * j a r _ b a s e n a m e * * Return the basename -- leading components of path stripped off, * extension ripped off -- of a path. * */static char *jar_basename (const char *path) { char *pith, *e, *basename, *ext; if (path == NULL) return PORT_Strdup (""); pith = PORT_Strdup (path); basename = pith; while (1) { for (e = basename; *e && *e != '/' && *e != '\\'; e++) /* yip */ ; if (*e) basename = ++e; else break; } if ((ext = PORT_Strrchr (basename, '.')) != NULL) *ext = 0; /* We already have the space allocated */ PORT_Strcpy (pith, basename); return pith; }/* * + + + + + + + + + + + + + + + * * CRYPTO ROUTINES FOR JAR * * The following functions are the cryptographic * interface to PKCS7 for Jarnatures. * * + + + + + + + + + + + + + + + * *//* * j a r _ c a t c h _ b y t e s * * In the event signatures contain enveloped data, it will show up here. * But note that the lib/pkcs7 routines aren't ready for it. * */static void jar_catch_bytes (void *arg, const char *buf, unsigned long len) { /* Actually this should never be called, since there is presumably no data in the signature itself. */ }/* * j a r _ v a l i d a t e _ p k c s 7 * * Validate (and decode, if necessary) a binary pkcs7 * signature in DER format. * */static int jar_validate_pkcs7 (JAR *jar, JAR_Signer *signer, char *data, long length) { SECItem detdig; SEC_PKCS7ContentInfo *cinfo; SEC_PKCS7DecoderContext *dcx; int status = 0; char *errstring = NULL; PORT_Assert( jar != NULL && signer != NULL ); if (jar == NULL || signer == NULL) return JAR_ERR_ORDER; signer->valid = JAR_ERR_SIG; /* We need a context if we can get one */#ifdef MOZILLA_CLIENT_OLD if (jar->mw == NULL) { JAR_set_context (jar, NULL); }#endif dcx = SEC_PKCS7DecoderStart (jar_catch_bytes, NULL /*cb_arg*/, NULL /*getpassword*/, jar->mw, NULL, NULL, NULL); if (dcx != NULL) { SEC_PKCS7DecoderUpdate (dcx, data, length); cinfo = SEC_PKCS7DecoderFinish (dcx); } if (cinfo == NULL) { /* strange pkcs7 failure */ return JAR_ERR_PK7; } if (SEC_PKCS7ContentIsEncrypted (cinfo)) { /* content was encrypted, fail */ return JAR_ERR_PK7; } if (SEC_PKCS7ContentIsSigned (cinfo) == PR_FALSE) { /* content was not signed, fail */ return JAR_ERR_PK7; } PORT_SetError (0); /* use SHA1 only */ detdig.len = SHA1_LENGTH; detdig.data = signer->digest->sha1;#ifdef USE_MOZ_THREAD if (jar_moz_verify (cinfo, certUsageObjectSigner, &detdig, HASH_AlgSHA1, PR_FALSE)== SECSuccess)#else if (SEC_PKCS7VerifyDetachedSignature (cinfo, certUsageObjectSigner, &detdig, HASH_AlgSHA1, PR_FALSE)== PR_TRUE)#endif { /* signature is valid */ signer->valid = 0; jar_gather_signers (jar, signer, cinfo); } else { status = PORT_GetError(); PORT_Assert( status < 0 ); if (status >= 0) status = JAR_ERR_SIG; jar->valid = status; signer->valid = status; errstring = JAR_get_error (status); /*XP_TRACE(("JAR signature invalid (reason %d = %s)", status, errstring));*/ } jar->pkcs7 = PR_TRUE; signer->pkcs7 = PR_TRUE; SEC_PKCS7DestroyContentInfo (cinfo); return status; }/* * j a r _ g a t h e r _ s i g n e r s * * Add the single signer of this signature to the * certificate linked list. * */static int jar_gather_signers (JAR *jar, JAR_Signer *signer, SEC_PKCS7ContentInfo *cinfo) { int result; CERTCertificate *cert; CERTCertDBHandle *certdb; SEC_PKCS7SignedData *sdp; SEC_PKCS7SignerInfo **pksigners, *pksigner; sdp = cinfo->content.signedData; if (sdp == NULL) return JAR_ERR_PK7; pksigners = sdp->signerInfos; /* permit exactly one signer */ if (pksigners == NULL || pksigners [0] == NULL || pksigners [1] != NULL) return JAR_ERR_PK7; pksigner = *pksigners; cert = pksigner->cert; if (cert == NULL) return JAR_ERR_PK7; certdb = JAR_open_database(); if (certdb == NULL) return JAR_ERR_GENERAL; result = jar_add_cert (jar, signer, jarTypeSign, cert); JAR_close_database (certdb); return result; }/* * j a r _ o p e n _ d a t a b a s e * * Open the certificate database, * for use by JAR functions. * */CERTCertDBHandle *JAR_open_database (void) { int keepcerts = 0; CERTCertDBHandle *certdb; /* local_certdb will only be used if calling from a command line tool */ static CERTCertDBHandle local_certdb; certdb = CERT_GetDefaultCertDB(); if (certdb == NULL) { if (CERT_OpenCertDBFilename (&local_certdb, NULL, (PRBool)!keepcerts) != SECSuccess) { return NULL; } certdb = &local_certdb; } return certdb; }/* * j a r _ c l o s e _ d a t a b a s e * * Close the certificate database. * For use by JAR functions. * */int JAR_close_database (CERTCertDBHandle *certdb) { CERTCertDBHandle *defaultdb; /* This really just retrieves the handle, nothing more */ defaultdb = CERT_GetDefaultCertDB(); /* If there is no default db, it means we opened the permanent database for some reason */ if (defaultdb == NULL && certdb != NULL) CERT_ClosePermCertDB (certdb); return 0; }/* * j a r _ g e t _ c e r t i f i c a t e * * Return the certificate referenced * by a given fingerprint, or NULL if not found. * Error code is returned in result. * */static CERTCertificate *jar_get_certificate (JAR *jar, long keylen, void *key, int *result) { int found = 0; JAR_Item *it; JAR_Cert *fing; JAR_Context *ctx; if (jar == NULL) { void *cert; cert = JAR_fetch_cert (keylen, key); *result = (cert == NULL) ? JAR_ERR_GENERAL : 0; return (CERTCertificate *) cert; } ctx = JAR_find (jar, NULL, jarTypeSign); while (JAR_find_next (ctx, &it) >= 0) { fing = (JAR_Cert *) it->data; if (keylen != fing->length) continue; PORT_Assert( keylen < 0xFFFF ); if (!PORT_Memcmp (fing->key, key, keylen)) { found = 1; break; } } JAR_find_end (ctx); if (found == 0) { *result = JAR_ERR_GENERAL; return NULL; } *result = 0; return fing->cert; }/* * j a r _ s i g n a l * * Nonfatal errors come here to callback Java. * */static int jar_signal (int status, JAR *jar, const char *metafile, char *pathname) { char *errstring; errstring = JAR_get_error (status); if (jar->signal) { (*jar->signal) (status, jar, metafile, pathname, errstring); return 0; } return status; }/* * j a r _ a p p e n d * * Tack on an element to one of a JAR's linked * lists, with rudimentary error handling. * */int jar_append (ZZList *list, int type, char *pathname, void *data, size_t size) { JAR_Item *it; ZZLink *entity; it = (JAR_Item*)PORT_ZAlloc (sizeof (JAR_Item)); if (it == NULL) goto loser; if (pathname) { it->pathname = PORT_Strdup (pathname); if (it->pathname == NULL) goto loser; } it->type = (jarType)type; it->data = (unsigned char *) data; it->size = size; entity = ZZ_NewLink (it); if (entity) { ZZ_AppendLink (list, entity); return 0; }loser: if (it) { if (it->pathname) PORT_Free (it->pathname); PORT_Free (it); } return JAR_ERR_MEMORY; }/* * W I N 1 6 s t u f f * * These functions possibly belong in xp_mem.c, they operate * on huge string pointers for win16. * */#if defined(XP_WIN16)int xp_HUGE_STRNCASECMP (char ZHUGEP *buf, char *key, int len) { while (len--) { char c1, c2; c1 = *buf++; c2 = *key++; if (c1 >= 'a' && c1 <= 'z') c1 -= ('a' - 'A'); if (c2 >= 'a' && c2 <= 'z') c2 -= ('a' - 'A'); if (c1 != c2) return (c1 < c2) ? -1 : 1; } return 0; }size_t xp_HUGE_STRLEN (char ZHUGEP *s) { size_t len = 0L; while (*s++) len++; return len; }char *xp_HUGE_STRCPY (char *to, char ZHUGEP *from) { char *ret = to; while (*from) *to++ = *from++; *to = 0; return ret; }#endif
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?