Back to index

lightning-sunbird  0.9+nobinonly
jarevil.c
Go to the documentation of this file.
00001 /* ***** BEGIN LICENSE BLOCK *****
00002  * Version: MPL 1.1/GPL 2.0/LGPL 2.1
00003  *
00004  * The contents of this file are subject to the Mozilla Public License Version
00005  * 1.1 (the "License"); you may not use this file except in compliance with
00006  * the License. You may obtain a copy of the License at
00007  * http://www.mozilla.org/MPL/
00008  *
00009  * Software distributed under the License is distributed on an "AS IS" basis,
00010  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
00011  * for the specific language governing rights and limitations under the
00012  * License.
00013  *
00014  * The Original Code is the Netscape security libraries.
00015  *
00016  * The Initial Developer of the Original Code is
00017  * Netscape Communications Corporation.
00018  * Portions created by the Initial Developer are Copyright (C) 1994-2000
00019  * the Initial Developer. All Rights Reserved.
00020  *
00021  * Contributor(s):
00022  *
00023  * Alternatively, the contents of this file may be used under the terms of
00024  * either the GNU General Public License Version 2 or later (the "GPL"), or
00025  * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
00026  * in which case the provisions of the GPL or the LGPL are applicable instead
00027  * of those above. If you wish to allow use of your version of this file only
00028  * under the terms of either the GPL or the LGPL, and not to allow others to
00029  * use your version of this file under the terms of the MPL, indicate your
00030  * decision by deleting the provisions above and replace them with the notice
00031  * and other provisions required by the GPL or the LGPL. If you do not delete
00032  * the provisions above, a recipient may use your version of this file under
00033  * the terms of any one of the MPL, the GPL or the LGPL.
00034  *
00035  * ***** END LICENSE BLOCK ***** */
00036 
00037 /*
00038  *  JAREVIL
00039  *
00040  *  Wrappers to callback in the mozilla thread
00041  *
00042  *  Certificate code is unsafe when called outside the
00043  *  mozilla thread. These functions push an event on the
00044  *  queue to cause the cert function to run in that thread. 
00045  *
00046  */
00047 
00048 #include "nssrenam.h"
00049 #include "jar.h"
00050 #include "jarint.h"
00051 
00052 #include "jarevil.h"
00053 #include "certdb.h"
00054 
00055 /* from libevent.h */
00056 #ifdef MOZILLA_CLIENT_OLD
00057 typedef void (*ETVoidPtrFunc) (void * data);
00058 extern void ET_moz_CallFunction (ETVoidPtrFunc fn, void *data);
00059 
00060 extern void *mozilla_event_queue;
00061 #endif
00062 
00063 
00064 /* Special macros facilitate running on Win 16 */
00065 #if defined(XP_WIN16)
00066 
00067   /* 
00068    * Allocate the data passed to the callback functions from the heap...
00069    *
00070    * This inter-thread structure cannot reside on a thread stack since the 
00071    * thread's stack is swapped away with the thread under Win16...
00072    */
00073 
00074  #define ALLOC_OR_DEFINE(type, pointer_var_name, out_of_memory_return_value) \
00075          type * pointer_var_name = PORT_ZAlloc (sizeof(type));               \
00076          do {                                                                \
00077            if (!pointer_var_name)                                            \
00078              return (out_of_memory_return_value);                            \
00079          } while (0)   /* and now a semicolon can follow :-) */
00080 
00081  #define FREE_IF_ALLOC_IS_USED(pointer_var_name) PORT_Free(pointer_var_name)
00082 
00083 #else /* not win 16... so we can alloc via auto variables */
00084 
00085  #define ALLOC_OR_DEFINE(type, pointer_var_name, out_of_memory_return_value) \
00086          type actual_structure_allocated_in_macro;                           \
00087          type * pointer_var_name = &actual_structure_allocated_in_macro;     \
00088          PORT_Memset (pointer_var_name, 0, sizeof (*pointer_var_name));      \
00089          ((void) 0) /* and now a semicolon can follow  */
00090 
00091  #define FREE_IF_ALLOC_IS_USED(pointer_var_name) ((void) 0)
00092 
00093 #endif /* not Win 16 */
00094 
00095 /* --- --- --- --- --- --- --- --- --- --- --- --- --- */
00096 
00097 /*
00098  *  JAR_MOZ_encode
00099  *
00100  *  Call SEC_PKCS7Encode inside
00101  *  the mozilla thread
00102  *
00103  */
00104 
00105 struct EVIL_encode
00106   {
00107   int error;
00108   SECStatus status;
00109   SEC_PKCS7ContentInfo *cinfo;
00110   SEC_PKCS7EncoderOutputCallback outputfn;
00111   void *outputarg;
00112   PK11SymKey *bulkkey;
00113   SECKEYGetPasswordKey pwfn;
00114   void *pwfnarg;
00115   };
00116 
00117 
00118 /* This is called inside the mozilla thread */
00119 
00120 PR_STATIC_CALLBACK(void) jar_moz_encode_fn (void *data)
00121   {
00122   SECStatus status;
00123   struct EVIL_encode *encode_data = (struct EVIL_encode *)data;
00124 
00125   PORT_SetError (encode_data->error);
00126 
00127   status = SEC_PKCS7Encode (encode_data->cinfo, encode_data->outputfn, 
00128                             encode_data->outputarg, encode_data->bulkkey, 
00129                             encode_data->pwfn, encode_data->pwfnarg);
00130 
00131   encode_data->status = status;
00132   encode_data->error = PORT_GetError();
00133   }
00134 
00135 
00136 /* Wrapper for the ET_MOZ call */
00137  
00138 SECStatus jar_moz_encode
00139       (
00140       SEC_PKCS7ContentInfo *cinfo,
00141       SEC_PKCS7EncoderOutputCallback  outputfn,
00142       void *outputarg,
00143       PK11SymKey *bulkkey,
00144       SECKEYGetPasswordKey pwfn,
00145       void *pwfnarg
00146       )
00147   {
00148   SECStatus ret;
00149   ALLOC_OR_DEFINE(struct EVIL_encode, encode_data, SECFailure);
00150 
00151   encode_data->error     = PORT_GetError();
00152   encode_data->cinfo     = cinfo;
00153   encode_data->outputfn  = outputfn;
00154   encode_data->outputarg = outputarg;
00155   encode_data->bulkkey   = bulkkey;
00156   encode_data->pwfn      = pwfn;
00157   encode_data->pwfnarg   = pwfnarg;
00158 
00159   /* Synchronously invoke the callback function on the mozilla thread. */
00160 #ifdef MOZILLA_CLIENT_OLD
00161   if (mozilla_event_queue)
00162     ET_moz_CallFunction (jar_moz_encode_fn, encode_data);
00163   else
00164     jar_moz_encode_fn (encode_data);
00165 #else
00166   jar_moz_encode_fn (encode_data);
00167 #endif
00168 
00169   PORT_SetError (encode_data->error);
00170   ret = encode_data->status;
00171 
00172   /* Free the data passed to the callback function... */
00173   FREE_IF_ALLOC_IS_USED(encode_data);
00174   return ret;
00175   }
00176 
00177 /* --- --- --- --- --- --- --- --- --- --- --- --- --- */
00178 
00179 /*
00180  *  JAR_MOZ_verify
00181  *
00182  *  Call SEC_PKCS7VerifyDetachedSignature inside
00183  *  the mozilla thread
00184  *
00185  */
00186 
00187 struct EVIL_verify
00188   {
00189   int error;
00190   SECStatus status;
00191   SEC_PKCS7ContentInfo *cinfo;
00192   SECCertUsage certusage;
00193   SECItem *detached_digest;
00194   HASH_HashType digest_type;
00195   PRBool keepcerts;
00196   };
00197 
00198 /* This is called inside the mozilla thread */
00199 
00200 PR_STATIC_CALLBACK(void) jar_moz_verify_fn (void *data)
00201   {
00202        PRBool result;
00203   struct EVIL_verify *verify_data = (struct EVIL_verify *)data;
00204 
00205   PORT_SetError (verify_data->error);
00206 
00207   result = SEC_PKCS7VerifyDetachedSignature
00208         (verify_data->cinfo, verify_data->certusage, verify_data->detached_digest, 
00209          verify_data->digest_type, verify_data->keepcerts);
00210        
00211 
00212   verify_data->status = result==PR_TRUE ? SECSuccess : SECFailure;
00213   verify_data->error = PORT_GetError();
00214   }
00215 
00216 
00217 /* Wrapper for the ET_MOZ call */
00218  
00219 SECStatus jar_moz_verify
00220       (
00221       SEC_PKCS7ContentInfo *cinfo,
00222       SECCertUsage certusage,
00223       SECItem *detached_digest,
00224       HASH_HashType digest_type,
00225       PRBool keepcerts
00226       )
00227   {
00228   SECStatus ret;
00229   ALLOC_OR_DEFINE(struct EVIL_verify, verify_data, SECFailure);
00230 
00231   verify_data->error           = PORT_GetError();
00232   verify_data->cinfo           = cinfo;
00233   verify_data->certusage       = certusage;
00234   verify_data->detached_digest = detached_digest;
00235   verify_data->digest_type     = digest_type;
00236   verify_data->keepcerts       = keepcerts;
00237 
00238   /* Synchronously invoke the callback function on the mozilla thread. */
00239 #ifdef MOZILLA_CLIENT_OLD
00240   if (mozilla_event_queue)
00241     ET_moz_CallFunction (jar_moz_verify_fn, verify_data);
00242   else
00243     jar_moz_verify_fn (verify_data);
00244 #else
00245   jar_moz_verify_fn (verify_data);
00246 #endif
00247 
00248   PORT_SetError (verify_data->error);
00249   ret = verify_data->status;
00250 
00251   /* Free the data passed to the callback function... */
00252   FREE_IF_ALLOC_IS_USED(verify_data);
00253   return ret;
00254   }
00255 
00256 /* --- --- --- --- --- --- --- --- --- --- --- --- --- */
00257 
00258 /*
00259  *  JAR_MOZ_nickname
00260  *
00261  *  Call CERT_FindCertByNickname inside
00262  *  the mozilla thread
00263  *
00264  */
00265 
00266 struct EVIL_nickname
00267   {
00268   int error;
00269   CERTCertDBHandle *certdb;
00270   char *nickname;
00271   CERTCertificate *cert;
00272   };
00273 
00274 
00275 /* This is called inside the mozilla thread */
00276 
00277 PR_STATIC_CALLBACK(void) jar_moz_nickname_fn (void *data)
00278   {
00279   CERTCertificate *cert;
00280   struct EVIL_nickname *nickname_data = (struct EVIL_nickname *)data;
00281 
00282   PORT_SetError (nickname_data->error);
00283 
00284   cert = CERT_FindCertByNickname (nickname_data->certdb, nickname_data->nickname);
00285 
00286   nickname_data->cert  = cert;
00287   nickname_data->error = PORT_GetError();
00288   }
00289 
00290 
00291 /* Wrapper for the ET_MOZ call */
00292  
00293 CERTCertificate *jar_moz_nickname (CERTCertDBHandle *certdb, char *nickname)
00294   {
00295   CERTCertificate *cert;
00296   ALLOC_OR_DEFINE(struct EVIL_nickname, nickname_data, NULL );
00297 
00298   nickname_data->error    = PORT_GetError();
00299   nickname_data->certdb   = certdb;
00300   nickname_data->nickname = nickname;
00301 
00302   /* Synchronously invoke the callback function on the mozilla thread. */
00303 #ifdef MOZILLA_CLIENT_OLD
00304   if (mozilla_event_queue)
00305     ET_moz_CallFunction (jar_moz_nickname_fn, nickname_data);
00306   else
00307     jar_moz_nickname_fn (nickname_data);
00308 #else
00309   jar_moz_nickname_fn (nickname_data);
00310 #endif
00311 
00312   PORT_SetError (nickname_data->error);
00313   cert = nickname_data->cert;
00314 
00315   /* Free the data passed to the callback function... */
00316   FREE_IF_ALLOC_IS_USED(nickname_data);
00317   return cert;
00318   }
00319 
00320 /* --- --- --- --- --- --- --- --- --- --- --- --- --- */
00321 
00322 /*
00323  *  JAR_MOZ_perm
00324  *
00325  *  Call CERT_AddTempCertToPerm inside
00326  *  the mozilla thread
00327  *
00328  */
00329 
00330 struct EVIL_perm
00331   {
00332   int error;
00333   SECStatus status;
00334   CERTCertificate *cert;
00335   char *nickname;
00336   CERTCertTrust *trust;
00337   };
00338 
00339 
00340 /* This is called inside the mozilla thread */
00341 
00342 PR_STATIC_CALLBACK(void) jar_moz_perm_fn (void *data)
00343   {
00344   SECStatus status;
00345   struct EVIL_perm *perm_data = (struct EVIL_perm *)data;
00346 
00347   PORT_SetError (perm_data->error);
00348 
00349   status = CERT_AddTempCertToPerm (perm_data->cert, perm_data->nickname, perm_data->trust);
00350 
00351   perm_data->status = status;
00352   perm_data->error = PORT_GetError();
00353   }
00354 
00355 
00356 /* Wrapper for the ET_MOZ call */
00357  
00358 SECStatus jar_moz_perm 
00359     (CERTCertificate *cert, char *nickname, CERTCertTrust *trust)
00360   {
00361   SECStatus ret;
00362   ALLOC_OR_DEFINE(struct EVIL_perm, perm_data, SECFailure);
00363 
00364   perm_data->error    = PORT_GetError();
00365   perm_data->cert     = cert;
00366   perm_data->nickname = nickname;
00367   perm_data->trust    = trust;
00368 
00369   /* Synchronously invoke the callback function on the mozilla thread. */
00370 #ifdef MOZILLA_CLIENT_OLD
00371   if (mozilla_event_queue)
00372     ET_moz_CallFunction (jar_moz_perm_fn, perm_data);
00373   else
00374     jar_moz_perm_fn (perm_data);
00375 #else
00376   jar_moz_perm_fn (perm_data);
00377 #endif
00378 
00379   PORT_SetError (perm_data->error);
00380   ret = perm_data->status;
00381 
00382   /* Free the data passed to the callback function... */
00383   FREE_IF_ALLOC_IS_USED(perm_data);
00384   return ret;
00385   }
00386 
00387 /* --- --- --- --- --- --- --- --- --- --- --- --- --- */
00388 
00389 /*
00390  *  JAR_MOZ_certkey
00391  *
00392  *  Call CERT_FindCertByKey inside
00393  *  the mozilla thread
00394  *
00395  */
00396 
00397 struct EVIL_certkey
00398   {
00399   int error;
00400   CERTCertificate *cert;
00401   CERTCertDBHandle *certdb;
00402   CERTIssuerAndSN *seckey;
00403   };
00404 
00405 
00406 /* This is called inside the mozilla thread */
00407 
00408 PR_STATIC_CALLBACK(void) jar_moz_certkey_fn (void *data)
00409   {
00410   CERTCertificate *cert;
00411   struct EVIL_certkey *certkey_data = (struct EVIL_certkey *)data;
00412 
00413   PORT_SetError (certkey_data->error);
00414 
00415   cert=CERT_FindCertByIssuerAndSN(certkey_data->certdb, certkey_data->seckey);
00416 
00417   certkey_data->cert = cert;
00418   certkey_data->error = PORT_GetError();
00419   }
00420 
00421 
00422 /* Wrapper for the ET_MOZ call */
00423  
00424 CERTCertificate *jar_moz_certkey (CERTCertDBHandle *certdb, 
00425                                           CERTIssuerAndSN *seckey)
00426   {
00427   CERTCertificate *cert;
00428   ALLOC_OR_DEFINE(struct EVIL_certkey, certkey_data, NULL);
00429 
00430   certkey_data->error  = PORT_GetError();
00431   certkey_data->certdb = certdb;
00432   certkey_data->seckey = seckey;
00433 
00434   /* Synchronously invoke the callback function on the mozilla thread. */
00435 #ifdef MOZILLA_CLIENT_OLD
00436   if (mozilla_event_queue)
00437     ET_moz_CallFunction (jar_moz_certkey_fn, certkey_data);
00438   else
00439     jar_moz_certkey_fn (certkey_data);
00440 #else
00441   jar_moz_certkey_fn (certkey_data);
00442 #endif
00443 
00444   PORT_SetError (certkey_data->error);
00445   cert = certkey_data->cert;
00446 
00447   /* Free the data passed to the callback function... */
00448   FREE_IF_ALLOC_IS_USED(certkey_data);
00449   return cert;
00450   }
00451 
00452 /* --- --- --- --- --- --- --- --- --- --- --- --- --- */
00453 
00454 /*
00455  *  JAR_MOZ_issuer
00456  *
00457  *  Call CERT_FindCertIssuer inside
00458  *  the mozilla thread
00459  *
00460  */
00461 
00462 struct EVIL_issuer
00463   {
00464   int error;
00465   CERTCertificate *cert;
00466   CERTCertificate *issuer;
00467   };
00468 
00469 
00470 /* This is called inside the mozilla thread */
00471 
00472 PR_STATIC_CALLBACK(void) jar_moz_issuer_fn (void *data)
00473   {
00474   CERTCertificate *issuer;
00475   struct EVIL_issuer *issuer_data = (struct EVIL_issuer *)data;
00476 
00477   PORT_SetError (issuer_data->error);
00478 
00479   issuer = CERT_FindCertIssuer (issuer_data->cert, PR_Now(),
00480                             certUsageObjectSigner);
00481 
00482   issuer_data->issuer = issuer;
00483   issuer_data->error = PORT_GetError();
00484   }
00485 
00486 
00487 /* Wrapper for the ET_MOZ call */
00488  
00489 CERTCertificate *jar_moz_issuer (CERTCertificate *cert)
00490   {
00491   CERTCertificate *issuer_cert;
00492   ALLOC_OR_DEFINE(struct EVIL_issuer, issuer_data, NULL);
00493 
00494   issuer_data->error = PORT_GetError();
00495   issuer_data->cert  = cert;
00496 
00497   /* Synchronously invoke the callback function on the mozilla thread. */
00498 #ifdef MOZILLA_CLIENT_OLD
00499   if (mozilla_event_queue)
00500     ET_moz_CallFunction (jar_moz_issuer_fn, issuer_data);
00501   else
00502     jar_moz_issuer_fn (issuer_data);
00503 #else
00504   jar_moz_issuer_fn (issuer_data);
00505 #endif
00506 
00507   PORT_SetError (issuer_data->error);
00508   issuer_cert = issuer_data->issuer;
00509 
00510   /* Free the data passed to the callback function... */
00511   FREE_IF_ALLOC_IS_USED(issuer_data);
00512   return issuer_cert;
00513   }
00514 
00515 /* --- --- --- --- --- --- --- --- --- --- --- --- --- */
00516 
00517 /*
00518  *  JAR_MOZ_dup
00519  *
00520  *  Call CERT_DupCertificate inside
00521  *  the mozilla thread
00522  *
00523  */
00524 
00525 struct EVIL_dup
00526   {
00527   int error;
00528   CERTCertificate *cert;
00529   CERTCertificate *return_cert;
00530   };
00531 
00532 
00533 /* This is called inside the mozilla thread */
00534 
00535 PR_STATIC_CALLBACK(void) jar_moz_dup_fn (void *data)
00536   {
00537   CERTCertificate *return_cert;
00538   struct EVIL_dup *dup_data = (struct EVIL_dup *)data;
00539 
00540   PORT_SetError (dup_data->error);
00541 
00542   return_cert = CERT_DupCertificate (dup_data->cert);
00543 
00544   dup_data->return_cert = return_cert;
00545   dup_data->error = PORT_GetError();
00546   }
00547 
00548 
00549 /* Wrapper for the ET_MOZ call */
00550  
00551 CERTCertificate *jar_moz_dup (CERTCertificate *cert)
00552   {
00553   CERTCertificate *dup_cert;
00554   ALLOC_OR_DEFINE(struct EVIL_dup, dup_data, NULL);
00555 
00556   dup_data->error = PORT_GetError();
00557   dup_data->cert  = cert;
00558 
00559   /* Synchronously invoke the callback function on the mozilla thread. */
00560 #ifdef MOZILLA_CLIENT_OLD
00561   if (mozilla_event_queue)
00562     ET_moz_CallFunction (jar_moz_dup_fn, dup_data);
00563   else
00564     jar_moz_dup_fn (dup_data);
00565 #else
00566   jar_moz_dup_fn (dup_data);
00567 #endif
00568 
00569   PORT_SetError (dup_data->error);
00570   dup_cert = dup_data->return_cert;
00571 
00572   /* Free the data passed to the callback function... */
00573   FREE_IF_ALLOC_IS_USED(dup_data);
00574   return dup_cert;
00575   }
00576 
00577 /* --- --- --- --- --- --- --- --- --- --- --- --- --- */