diff options
Diffstat (limited to 'security/nss/lib/jar/jarevil.c')
-rw-r--r-- | security/nss/lib/jar/jarevil.c | 573 |
1 files changed, 573 insertions, 0 deletions
diff --git a/security/nss/lib/jar/jarevil.c b/security/nss/lib/jar/jarevil.c new file mode 100644 index 000000000..cced82b7d --- /dev/null +++ b/security/nss/lib/jar/jarevil.c @@ -0,0 +1,573 @@ +/* + * 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. + */ + +/* + * JAREVIL + * + * Wrappers to callback in the mozilla thread + * + * Certificate code is unsafe when called outside the + * mozilla thread. These functions push an event on the + * queue to cause the cert function to run in that thread. + * + */ + +#include "jar.h" +#include "jarint.h" + +#include "jarevil.h" +#include "certdb.h" + +/* from libevent.h */ +#ifdef MOZILLA_CLIENT_OLD +typedef void (*ETVoidPtrFunc) (void * data); +extern void ET_moz_CallFunction (ETVoidPtrFunc fn, void *data); + +extern void *mozilla_event_queue; +#endif + + +/* Special macros facilitate running on Win 16 */ +#if defined(XP_WIN16) + + /* + * Allocate the data passed to the callback functions from the heap... + * + * This inter-thread structure cannot reside on a thread stack since the + * thread's stack is swapped away with the thread under Win16... + */ + + #define ALLOC_OR_DEFINE(type, pointer_var_name, out_of_memory_return_value) \ + type * pointer_var_name = PORT_ZAlloc (sizeof(type)); \ + do { \ + if (!pointer_var_name) \ + return (out_of_memory_return_value); \ + } while (0) /* and now a semicolon can follow :-) */ + + #define FREE_IF_ALLOC_IS_USED(pointer_var_name) PORT_Free(pointer_var_name) + +#else /* not win 16... so we can alloc via auto variables */ + + #define ALLOC_OR_DEFINE(type, pointer_var_name, out_of_memory_return_value) \ + type actual_structure_allocated_in_macro; \ + type * pointer_var_name = &actual_structure_allocated_in_macro; \ + PORT_Memset (pointer_var_name, 0, sizeof (*pointer_var_name)); \ + ((void) 0) /* and now a semicolon can follow */ + + #define FREE_IF_ALLOC_IS_USED(pointer_var_name) ((void) 0) + +#endif /* not Win 16 */ + +/* --- --- --- --- --- --- --- --- --- --- --- --- --- */ + +/* + * JAR_MOZ_encode + * + * Call SEC_PKCS7Encode inside + * the mozilla thread + * + */ + +struct EVIL_encode + { + int error; + SECStatus status; + SEC_PKCS7ContentInfo *cinfo; + SEC_PKCS7EncoderOutputCallback outputfn; + void *outputarg; + PK11SymKey *bulkkey; + SECKEYGetPasswordKey pwfn; + void *pwfnarg; + }; + + +/* This is called inside the mozilla thread */ + +PR_STATIC_CALLBACK(void) jar_moz_encode_fn (void *data) + { + SECStatus status; + struct EVIL_encode *encode_data = (struct EVIL_encode *)data; + + PORT_SetError (encode_data->error); + + status = SEC_PKCS7Encode (encode_data->cinfo, encode_data->outputfn, + encode_data->outputarg, encode_data->bulkkey, + encode_data->pwfn, encode_data->pwfnarg); + + encode_data->status = status; + encode_data->error = PORT_GetError(); + } + + +/* Wrapper for the ET_MOZ call */ + +SECStatus jar_moz_encode + ( + SEC_PKCS7ContentInfo *cinfo, + SEC_PKCS7EncoderOutputCallback outputfn, + void *outputarg, + PK11SymKey *bulkkey, + SECKEYGetPasswordKey pwfn, + void *pwfnarg + ) + { + SECStatus ret; + ALLOC_OR_DEFINE(struct EVIL_encode, encode_data, SECFailure); + + encode_data->error = PORT_GetError(); + encode_data->cinfo = cinfo; + encode_data->outputfn = outputfn; + encode_data->outputarg = outputarg; + encode_data->bulkkey = bulkkey; + encode_data->pwfn = pwfn; + encode_data->pwfnarg = pwfnarg; + + /* Synchronously invoke the callback function on the mozilla thread. */ +#ifdef MOZILLA_CLIENT_OLD + if (mozilla_event_queue) + ET_moz_CallFunction (jar_moz_encode_fn, encode_data); + else + jar_moz_encode_fn (encode_data); +#else + jar_moz_encode_fn (encode_data); +#endif + + PORT_SetError (encode_data->error); + ret = encode_data->status; + + /* Free the data passed to the callback function... */ + FREE_IF_ALLOC_IS_USED(encode_data); + return ret; + } + +/* --- --- --- --- --- --- --- --- --- --- --- --- --- */ + +/* + * JAR_MOZ_verify + * + * Call SEC_PKCS7VerifyDetachedSignature inside + * the mozilla thread + * + */ + +struct EVIL_verify + { + int error; + SECStatus status; + SEC_PKCS7ContentInfo *cinfo; + SECCertUsage certusage; + SECItem *detached_digest; + HASH_HashType digest_type; + PRBool keepcerts; + }; + +/* This is called inside the mozilla thread */ + +PR_STATIC_CALLBACK(void) jar_moz_verify_fn (void *data) + { + PRBool result; + struct EVIL_verify *verify_data = (struct EVIL_verify *)data; + + PORT_SetError (verify_data->error); + + result = SEC_PKCS7VerifyDetachedSignature + (verify_data->cinfo, verify_data->certusage, verify_data->detached_digest, + verify_data->digest_type, verify_data->keepcerts); + + + verify_data->status = result==PR_TRUE ? SECSuccess : SECFailure; + verify_data->error = PORT_GetError(); + } + + +/* Wrapper for the ET_MOZ call */ + +SECStatus jar_moz_verify + ( + SEC_PKCS7ContentInfo *cinfo, + SECCertUsage certusage, + SECItem *detached_digest, + HASH_HashType digest_type, + PRBool keepcerts + ) + { + SECStatus ret; + ALLOC_OR_DEFINE(struct EVIL_verify, verify_data, SECFailure); + + verify_data->error = PORT_GetError(); + verify_data->cinfo = cinfo; + verify_data->certusage = certusage; + verify_data->detached_digest = detached_digest; + verify_data->digest_type = digest_type; + verify_data->keepcerts = keepcerts; + + /* Synchronously invoke the callback function on the mozilla thread. */ +#ifdef MOZILLA_CLIENT_OLD + if (mozilla_event_queue) + ET_moz_CallFunction (jar_moz_verify_fn, verify_data); + else + jar_moz_verify_fn (verify_data); +#else + jar_moz_verify_fn (verify_data); +#endif + + PORT_SetError (verify_data->error); + ret = verify_data->status; + + /* Free the data passed to the callback function... */ + FREE_IF_ALLOC_IS_USED(verify_data); + return ret; + } + +/* --- --- --- --- --- --- --- --- --- --- --- --- --- */ + +/* + * JAR_MOZ_nickname + * + * Call CERT_FindCertByNickname inside + * the mozilla thread + * + */ + +struct EVIL_nickname + { + int error; + CERTCertDBHandle *certdb; + char *nickname; + CERTCertificate *cert; + }; + + +/* This is called inside the mozilla thread */ + +PR_STATIC_CALLBACK(void) jar_moz_nickname_fn (void *data) + { + CERTCertificate *cert; + struct EVIL_nickname *nickname_data = (struct EVIL_nickname *)data; + + PORT_SetError (nickname_data->error); + + cert = CERT_FindCertByNickname (nickname_data->certdb, nickname_data->nickname); + + nickname_data->cert = cert; + nickname_data->error = PORT_GetError(); + } + + +/* Wrapper for the ET_MOZ call */ + +CERTCertificate *jar_moz_nickname (CERTCertDBHandle *certdb, char *nickname) + { + CERTCertificate *cert; + ALLOC_OR_DEFINE(struct EVIL_nickname, nickname_data, NULL ); + + nickname_data->error = PORT_GetError(); + nickname_data->certdb = certdb; + nickname_data->nickname = nickname; + + /* Synchronously invoke the callback function on the mozilla thread. */ +#ifdef MOZILLA_CLIENT_OLD + if (mozilla_event_queue) + ET_moz_CallFunction (jar_moz_nickname_fn, nickname_data); + else + jar_moz_nickname_fn (nickname_data); +#else + jar_moz_nickname_fn (nickname_data); +#endif + + PORT_SetError (nickname_data->error); + cert = nickname_data->cert; + + /* Free the data passed to the callback function... */ + FREE_IF_ALLOC_IS_USED(nickname_data); + return cert; + } + +/* --- --- --- --- --- --- --- --- --- --- --- --- --- */ + +/* + * JAR_MOZ_perm + * + * Call CERT_AddTempCertToPerm inside + * the mozilla thread + * + */ + +struct EVIL_perm + { + int error; + SECStatus status; + CERTCertificate *cert; + char *nickname; + CERTCertTrust *trust; + }; + + +/* This is called inside the mozilla thread */ + +PR_STATIC_CALLBACK(void) jar_moz_perm_fn (void *data) + { + SECStatus status; + struct EVIL_perm *perm_data = (struct EVIL_perm *)data; + + PORT_SetError (perm_data->error); + + status = CERT_AddTempCertToPerm (perm_data->cert, perm_data->nickname, perm_data->trust); + + perm_data->status = status; + perm_data->error = PORT_GetError(); + } + + +/* Wrapper for the ET_MOZ call */ + +SECStatus jar_moz_perm + (CERTCertificate *cert, char *nickname, CERTCertTrust *trust) + { + SECStatus ret; + ALLOC_OR_DEFINE(struct EVIL_perm, perm_data, SECFailure); + + perm_data->error = PORT_GetError(); + perm_data->cert = cert; + perm_data->nickname = nickname; + perm_data->trust = trust; + + /* Synchronously invoke the callback function on the mozilla thread. */ +#ifdef MOZILLA_CLIENT_OLD + if (mozilla_event_queue) + ET_moz_CallFunction (jar_moz_perm_fn, perm_data); + else + jar_moz_perm_fn (perm_data); +#else + jar_moz_perm_fn (perm_data); +#endif + + PORT_SetError (perm_data->error); + ret = perm_data->status; + + /* Free the data passed to the callback function... */ + FREE_IF_ALLOC_IS_USED(perm_data); + return ret; + } + +/* --- --- --- --- --- --- --- --- --- --- --- --- --- */ + +/* + * JAR_MOZ_certkey + * + * Call CERT_FindCertByKey inside + * the mozilla thread + * + */ + +struct EVIL_certkey + { + int error; + CERTCertificate *cert; + CERTCertDBHandle *certdb; + CERTIssuerAndSN *seckey; + }; + + +/* This is called inside the mozilla thread */ + +PR_STATIC_CALLBACK(void) jar_moz_certkey_fn (void *data) + { + CERTCertificate *cert; + struct EVIL_certkey *certkey_data = (struct EVIL_certkey *)data; + + PORT_SetError (certkey_data->error); + + cert=CERT_FindCertByIssuerAndSN(certkey_data->certdb, certkey_data->seckey); + + certkey_data->cert = cert; + certkey_data->error = PORT_GetError(); + } + + +/* Wrapper for the ET_MOZ call */ + +CERTCertificate *jar_moz_certkey (CERTCertDBHandle *certdb, + CERTIssuerAndSN *seckey) + { + CERTCertificate *cert; + ALLOC_OR_DEFINE(struct EVIL_certkey, certkey_data, NULL); + + certkey_data->error = PORT_GetError(); + certkey_data->certdb = certdb; + certkey_data->seckey = seckey; + + /* Synchronously invoke the callback function on the mozilla thread. */ +#ifdef MOZILLA_CLIENT_OLD + if (mozilla_event_queue) + ET_moz_CallFunction (jar_moz_certkey_fn, certkey_data); + else + jar_moz_certkey_fn (certkey_data); +#else + jar_moz_certkey_fn (certkey_data); +#endif + + PORT_SetError (certkey_data->error); + cert = certkey_data->cert; + + /* Free the data passed to the callback function... */ + FREE_IF_ALLOC_IS_USED(certkey_data); + return cert; + } + +/* --- --- --- --- --- --- --- --- --- --- --- --- --- */ + +/* + * JAR_MOZ_issuer + * + * Call CERT_FindCertIssuer inside + * the mozilla thread + * + */ + +struct EVIL_issuer + { + int error; + CERTCertificate *cert; + CERTCertificate *issuer; + }; + + +/* This is called inside the mozilla thread */ + +PR_STATIC_CALLBACK(void) jar_moz_issuer_fn (void *data) + { + CERTCertificate *issuer; + struct EVIL_issuer *issuer_data = (struct EVIL_issuer *)data; + + PORT_SetError (issuer_data->error); + + issuer = CERT_FindCertIssuer (issuer_data->cert, PR_Now(), + certUsageObjectSigner); + + issuer_data->issuer = issuer; + issuer_data->error = PORT_GetError(); + } + + +/* Wrapper for the ET_MOZ call */ + +CERTCertificate *jar_moz_issuer (CERTCertificate *cert) + { + CERTCertificate *issuer_cert; + ALLOC_OR_DEFINE(struct EVIL_issuer, issuer_data, NULL); + + issuer_data->error = PORT_GetError(); + issuer_data->cert = cert; + + /* Synchronously invoke the callback function on the mozilla thread. */ +#ifdef MOZILLA_CLIENT_OLD + if (mozilla_event_queue) + ET_moz_CallFunction (jar_moz_issuer_fn, issuer_data); + else + jar_moz_issuer_fn (issuer_data); +#else + jar_moz_issuer_fn (issuer_data); +#endif + + PORT_SetError (issuer_data->error); + issuer_cert = issuer_data->issuer; + + /* Free the data passed to the callback function... */ + FREE_IF_ALLOC_IS_USED(issuer_data); + return issuer_cert; + } + +/* --- --- --- --- --- --- --- --- --- --- --- --- --- */ + +/* + * JAR_MOZ_dup + * + * Call CERT_DupCertificate inside + * the mozilla thread + * + */ + +struct EVIL_dup + { + int error; + CERTCertificate *cert; + CERTCertificate *return_cert; + }; + + +/* This is called inside the mozilla thread */ + +PR_STATIC_CALLBACK(void) jar_moz_dup_fn (void *data) + { + CERTCertificate *return_cert; + struct EVIL_dup *dup_data = (struct EVIL_dup *)data; + + PORT_SetError (dup_data->error); + + return_cert = CERT_DupCertificate (dup_data->cert); + + dup_data->return_cert = return_cert; + dup_data->error = PORT_GetError(); + } + + +/* Wrapper for the ET_MOZ call */ + +CERTCertificate *jar_moz_dup (CERTCertificate *cert) + { + CERTCertificate *dup_cert; + ALLOC_OR_DEFINE(struct EVIL_dup, dup_data, NULL); + + dup_data->error = PORT_GetError(); + dup_data->cert = cert; + + /* Synchronously invoke the callback function on the mozilla thread. */ +#ifdef MOZILLA_CLIENT_OLD + if (mozilla_event_queue) + ET_moz_CallFunction (jar_moz_dup_fn, dup_data); + else + jar_moz_dup_fn (dup_data); +#else + jar_moz_dup_fn (dup_data); +#endif + + PORT_SetError (dup_data->error); + dup_cert = dup_data->return_cert; + + /* Free the data passed to the callback function... */ + FREE_IF_ALLOC_IS_USED(dup_data); + return dup_cert; + } + +/* --- --- --- --- --- --- --- --- --- --- --- --- --- */ |