certres.c
上传用户:lyxiangda
上传日期:2007-01-12
资源大小:3042k
文件大小:78k
源码类别:

CA认证

开发平台:

WINDOWS

  1. /*
  2.  * The contents of this file are subject to the Mozilla Public
  3.  * License Version 1.1 (the "License"); you may not use this file
  4.  * except in compliance with the License. You may obtain a copy of
  5.  * the License at http://www.mozilla.org/MPL/
  6.  * 
  7.  * Software distributed under the License is distributed on an "AS
  8.  * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
  9.  * implied. See the License for the specific language governing
  10.  * rights and limitations under the License.
  11.  * 
  12.  * The Original Code is the Netscape security libraries.
  13.  * 
  14.  * The Initial Developer of the Original Code is Netscape
  15.  * Communications Corporation.  Portions created by Netscape are 
  16.  * Copyright (C) 1994-2000 Netscape Communications Corporation.  All
  17.  * Rights Reserved.
  18.  * 
  19.  * Contributor(s):
  20.  * 
  21.  * Alternatively, the contents of this file may be used under the
  22.  * terms of the GNU General Public License Version 2 or later (the
  23.  * "GPL"), in which case the provisions of the GPL are applicable 
  24.  * instead of those above.  If you wish to allow use of your 
  25.  * version of this file only under the terms of the GPL and not to
  26.  * allow others to use your version of this file under the MPL,
  27.  * indicate your decision by deleting the provisions above and
  28.  * replace them with the notice and other provisions required by
  29.  * the GPL.  If you do not delete the provisions above, a recipient
  30.  * may use your version of this file under either the MPL or the
  31.  * GPL.
  32.  */
  33. #include "certres.h"
  34. #include "sechash.h"
  35. #include "ssmerrs.h"
  36. #include "ctrlconn.h"
  37. #include "certlist.h"
  38. #include "resource.h"
  39. #include "ssldlgs.h"
  40. #include "certsearch.h"
  41. #include "secpkcs7.h"
  42. #include "secerr.h"
  43. #include "advisor.h"
  44. typedef enum 
  45. { myCert = 0,
  46.   othersCert,
  47.   webCert,
  48.   caCert,
  49.   badCert
  50. } certPane;
  51. enum {
  52.   USER_CERT = (PRIntn) 0, 
  53.   EMAIL_CERT, 
  54.   CA_CERT, 
  55.   WEBSITE_CERT
  56. };
  57. enum { 
  58.   NICKNAME = (PRIntn) 0,
  59.   EMAILADDR
  60. };
  61. SSMStatus SSM_DeleteCertificate(SSMResourceCert * resource);
  62. SECItem * unhexify(char * hex);
  63. SSMStatus
  64. ssm_select_cert(SSMTextGenContext * cx, char ** result, char * fmt, 
  65.         PRIntn type, PRIntn key, char * nickname);
  66. SSMStatus
  67. ssm_create_select_cert_entry(SSMTextGenContext * cx, CERTCertificate * cert, 
  68.      char **result, char *fmt, char * checked);
  69. SSMStatus
  70. ssm_cert_belongs_type(CERTCertificate * cert, PRIntn type);
  71. static
  72. certPane SSMUI_CertBelongs(CERTCertificate * cert);
  73. /* ### mwelch Defined in libcert. Should we be using this? */
  74. SEC_BEGIN_PROTOS
  75. extern SECStatus cert_GetKeyID(CERTCertificate *cert);
  76. SEC_END_PROTOS
  77. CERTCertificate * FindCertByKeyIDAndNickname(SSMControlConnection * ctrl, 
  78.      char *nickname, SECItem *keyID, 
  79.      char * serial);
  80. CERTCertList * 
  81. SSMControlConnection_CreateCertListByNickname(SSMControlConnection * ctrl, 
  82.       char * nick, PRBool email);
  83. CERTCertificate * 
  84. SSMControlConnection_FindCertByNickname(SSMControlConnection * ctrl, 
  85. char * nick, PRBool email);
  86. SSMStatus SSM_RefreshRefererPage(HTTPRequest * req);
  87. SSMStatus SSM_ProcessCertResourceUIAction(HTTPRequest * req, 
  88.   SSMResourceCert * certres);
  89. extern SSMStatus httpparse_count_params(HTTPRequest * req);
  90. extern SSMStatus httpparse_parse_params(HTTPRequest * req);
  91. /* Shorthand macros for inherited classes */
  92. #define SSMRESOURCE(ss) (&(ss)->super)
  93. SSMStatus SSMResourceCert_GetAttr(SSMResource * resource, 
  94.   SSMAttributeID attrib,
  95.   SSMResourceAttrType attrType,
  96.   SSMAttributeValue *value)
  97. {
  98.   SSMResourceCert * res = (SSMResourceCert *)resource;
  99.   SECItem secitem;
  100.   SSMStatus rv;
  101.   char *tmpstr = NULL;
  102.   if (!res || !res->cert || !value )
  103.     goto loser;
  104.   /* Access fields in the certificate and pass up in the data field */
  105.   switch (attrib) {
  106.   case SSM_FID_CERT_SUBJECT_NAME:
  107.     if (!res->cert->subjectName) 
  108.       goto loser;
  109.     value->type = SSM_STRING_ATTRIBUTE;
  110.     value->u.string.len = strlen(res->cert->subjectName);
  111.     value->u.string.data = (unsigned char *) strdup(res->cert->subjectName);
  112.     break;
  113.     
  114.   case SSM_FID_CERT_ISSUER_NAME:
  115.     if (!res->cert->issuerName) 
  116.       goto loser;
  117.     value->type = SSM_STRING_ATTRIBUTE;
  118.     value->u.string.len = strlen(res->cert->issuerName);
  119.     value->u.string.data = (unsigned char *) strdup(res->cert->issuerName);
  120.     break;
  121.     
  122.   case SSM_FID_CERT_SERIAL_NUMBER:
  123.     value->type = SSM_STRING_ATTRIBUTE;
  124.     tmpstr = CERT_Hexify(&(res->cert->serialNumber), 1);
  125.     if (tmpstr == NULL)
  126.       goto loser;
  127.     value->u.string.len = strlen(tmpstr);
  128.     value->u.string.data = (unsigned char *) strdup(tmpstr);
  129.     break;
  130.   case SSM_FID_CERT_EXP_DATE:
  131.     value->type = SSM_STRING_ATTRIBUTE;
  132.     tmpstr = DER_UTCDayToAscii(&(res->cert->validity.notAfter));
  133.     if (tmpstr == NULL)
  134.       goto loser;
  135.     value->u.string.len = strlen(tmpstr);
  136.     value->u.string.data = (unsigned char *) strdup(tmpstr);
  137.     break;
  138.   case SSM_FID_CERT_FINGERPRINT:
  139.     {
  140.       unsigned char buf[MD5_LENGTH];
  141.       value->type = SSM_STRING_ATTRIBUTE;
  142.       MD5_HashBuf(buf, res->cert->derCert.data, res->cert->derCert.len);
  143.       secitem.data = buf;
  144.       secitem.len = 16;
  145.       tmpstr = CERT_Hexify(&secitem, 1);
  146.       if (tmpstr == NULL)
  147.     goto loser;
  148.       value->u.string.len = strlen(tmpstr);
  149.       value->u.string.data = (unsigned char *) strdup(tmpstr);
  150.       break;
  151.     }
  152.     
  153.   case SSM_FID_CERT_COMMON_NAME:
  154.     value->type = SSM_STRING_ATTRIBUTE;
  155.     tmpstr = CERT_GetCommonName(&(res->cert->subject));
  156.     if (tmpstr == NULL)
  157.       goto loser;
  158.     value->u.string.len = strlen(tmpstr);
  159.     value->u.string.data = (unsigned char *) strdup(tmpstr);
  160.     break;
  161.     
  162.   case SSM_FID_CERT_NICKNAME:
  163.     if (!res->cert->nickname) 
  164.       goto loser;
  165.     value->type = SSM_STRING_ATTRIBUTE;
  166.     value->u.string.len = strlen(res->cert->nickname);
  167.     value->u.string.data = (unsigned char *) strdup(res->cert->nickname);
  168.     break;
  169.     
  170.   case SSM_FID_CERT_ORG_NAME:
  171.     value->type = SSM_STRING_ATTRIBUTE;
  172.     tmpstr = CERT_GetOrgName(&(res->cert->subject));
  173.     if (tmpstr == NULL)
  174.       goto loser;
  175.     value->u.string.len = strlen(tmpstr);
  176.     value->u.string.data = (unsigned char *) strdup(tmpstr);
  177.     break;
  178.   case SSM_FID_CERT_EMAIL_ADDRESS:
  179.     value->type = SSM_STRING_ATTRIBUTE;
  180.     tmpstr = PL_strdup(CERT_GetCertificateEmailAddress(res->cert));
  181.     if (tmpstr == NULL)
  182.       goto loser;
  183.     value->u.string.len = PL_strlen(tmpstr);
  184.     value->u.string.data = (unsigned char *) PL_strdup(tmpstr);
  185.     break;
  186.     
  187.   case SSM_FID_CERT_PICKLE_CERT:
  188.     value->type = SSM_STRING_ATTRIBUTE;
  189.     if (!(value->u.string.data = (unsigned char *) PR_Malloc(res->cert->derCert.len))) {
  190.         goto loser;
  191.     }
  192.     memcpy(value->u.string.data, res->cert->derCert.data, res->cert->derCert.len);
  193.     value->u.string.len = res->cert->derCert.len;
  194.     break;
  195.   case SSM_FID_CERT_HTML_CERT:
  196.     value->type = SSM_STRING_ATTRIBUTE;
  197.     rv = (*resource->m_html_func)(resource, NULL, (void **)&tmpstr);
  198.     if (rv != PR_SUCCESS)
  199.       goto loser;
  200.     value->u.string.len = PL_strlen(tmpstr);
  201.     value->u.string.data = (unsigned char *) PL_strdup(tmpstr);
  202.     break;
  203.   case SSM_FID_CERT_CERTKEY:
  204.       value->type = SSM_STRING_ATTRIBUTE;
  205.       if (!(value->u.string.data = (unsigned char *) PR_Malloc(res->cert->certKey.len))) {
  206.           goto loser;
  207.       }
  208.       memcpy(value->u.string.data, res->cert->certKey.data, res->cert->certKey.len);
  209.       value->u.string.len = res->cert->certKey.len;
  210.       break;
  211.   case SSM_FID_CERT_FIND_CERT_ISSUER:
  212.       {
  213.         SSMResourceCert *certRes;
  214.         SSMResourceID certID;
  215.         SSMStatus rv;
  216.         CERTCertificate *cert;
  217.         /* Make sure we have a cert to return. */
  218.         cert = CERT_FindCertIssuer(res->cert, PR_Now(), certUsageObjectSigner);
  219.         if (!cert) {
  220.             goto loser;
  221.         }
  222.         if ((cert->certKey.len != res->cert->certKey.len) ||
  223.             (memcmp(cert->certKey.data, 
  224.                     res->cert->certKey.data, 
  225.                     cert->certKey.len)))
  226.         {
  227.             rv = SSM_CreateResource(SSM_RESTYPE_CERTIFICATE,
  228.     cert, resource->m_connection, &certID,
  229.     (SSMResource**)&certRes);
  230.     if (rv != PR_SUCCESS)
  231.       goto loser;
  232.     rv = SSM_ClientGetResourceReference(SSMRESOURCE(certRes), &certID);
  233.     SSM_FreeResource(SSMRESOURCE(certRes));
  234.     if (rv != PR_SUCCESS)
  235.       goto loser;
  236.         }
  237.         else
  238.         {
  239.     rv = SSM_ClientGetResourceReference(SSMRESOURCE(res), &certID);
  240.     if (rv != PR_SUCCESS)
  241.       goto loser;
  242.         }
  243.         value->type = SSM_RID_ATTRIBUTE;
  244. value->u.rid = certID;
  245.         rv = PR_SUCCESS;
  246.         break;
  247.         }
  248.     case SSM_FID_CERT_ISPERM:
  249.         value->type = SSM_NUMERIC_ATTRIBUTE;
  250.         value->u.numeric = res->cert->isperm;
  251.         rv = PR_SUCCESS;
  252.         break;
  253.   default: 
  254.     goto loser;
  255.   }
  256.   if (tmpstr != NULL)
  257.     PR_Free(tmpstr);
  258.   return PR_SUCCESS;
  259.   
  260. loser:
  261.   value->type = SSM_NO_ATTRIBUTE;
  262.   if (tmpstr != NULL)
  263.     PR_Free(tmpstr);
  264.   return PR_FAILURE;
  265. }
  266. SSMStatus SSMResourceCert_Pickle(SSMResource * res, 
  267. PRIntn * len,
  268. void ** data)
  269. {
  270.   SSMAttributeValue value;
  271.   SSMStatus rv;
  272.   if (!res || !((SSMResourceCert *)res)->cert || !data || !len ) 
  273.     return PR_FAILURE;
  274.   rv =  ((*(SSMResourceCert *)res).super.m_get_func)(res,
  275.      SSM_FID_CERT_PICKLE_CERT,
  276.      SSM_STRING_ATTRIBUTE,
  277.      &value);
  278.   if (rv != PR_SUCCESS)
  279.     goto loser;
  280.   *data = PR_Malloc(value.u.string.len);
  281.   if (!*data) { 
  282.       goto loser;
  283.   }
  284.   memcpy(*data, value.u.string.data, value.u.string.len);
  285.   *len = value.u.string.len;
  286.   SSM_DestroyAttrValue(&value, PR_FALSE);
  287. loser:
  288.   return rv;
  289. }
  290. SSMStatus SSMResourceCert_GetAttrIDs(SSMResource *res,
  291.     SSMAttributeID **ids,
  292.     PRIntn *count)
  293. {
  294.   int i=-1;
  295.   
  296.   if (!res || !ids || !count) 
  297.     goto loser;
  298.   
  299.   /* all certificate attributes accessible to client */
  300.   *count = SSM_FID_CERT_ORG_NAME - SSM_FID_CERT_SUBJECT_NAME + 1;
  301.   *ids = (SSMAttributeID *)PORT_ZAlloc(*count * (sizeof(SSMAttributeID)));
  302.   if (!*ids) goto loser;
  303.   while (i < *count) {
  304.     (*ids)[i] = (SSMAttributeID) ((int) SSM_FID_CERT_SUBJECT_NAME + i);
  305.     i++;
  306.   }
  307.   return PR_SUCCESS;
  308.   
  309. loser:
  310.   return PR_FAILURE;
  311. }
  312. SSMStatus
  313. SSMResourceCert_Create(void *arg, SSMControlConnection * connection, 
  314.        SSMResource **res)
  315. {
  316.   SSMStatus rv = PR_SUCCESS;
  317.   SSMResourceCert * certResource = NULL;
  318.   if (!res) 
  319.     goto loser;
  320.   *res = NULL;
  321.   
  322.   if (!arg)
  323.     goto loser;
  324.   
  325.   /* before creating a cert, make sure we don't have it already */
  326.   SSMControlConnection_CertLookUp(connection, arg, res);
  327.   if (*res) 
  328.     goto done; /* found cert resource! */
  329.   certResource = (SSMResourceCert *)PR_CALLOC(sizeof(SSMResourceCert));
  330.   if (!certResource) 
  331.     goto loser;
  332.   rv = SSMResourceCert_Init(certResource, connection, arg);
  333.   if (rv != PR_SUCCESS) goto loser;
  334.   
  335.   *res = (SSMResource *)&certResource->super;
  336.   /* enter cert into cert db */
  337.   rv = SSM_HashInsert(connection->m_certIdDB, (SSMHashKey) arg, (void *)*res);
  338.   if (rv != PR_SUCCESS) 
  339.     goto loser;
  340. done:
  341.   return PR_SUCCESS;
  342. loser:
  343.   if (certResource) 
  344.     (*((SSMRESOURCE(certResource))->m_destroy_func))
  345.       ((SSMResource *)certResource, PR_TRUE);
  346.   else 
  347.     if (arg) 
  348.       PR_Free(arg); 
  349.   return PR_FAILURE;
  350. }
  351. SSMStatus SSMResourceCert_Init(SSMResourceCert * certResource,
  352.       SSMControlConnection * conn,
  353.       void * arg)
  354.      
  355. {
  356.   SSMResource_Init(conn, SSMRESOURCE(certResource), SSM_RESTYPE_CERTIFICATE);
  357.   certResource->cert = (CERTCertificate *)arg;
  358.   if (!arg) 
  359.     return SSM_FAILURE;
  360.   if (certResource->cert->slot) 
  361.     PK11_ReferenceSlot(certResource->cert->slot);
  362.   certResource->m_verify_func = &SSMResourceCert_Verify;
  363.   certResource->m_deletecert_func = &SSMResourceCert_DeleteCert;
  364.   certResource->m_markedForDeletion = PR_FALSE;
  365.   return SSM_SUCCESS;
  366. }
  367. SSMStatus SSMResourceCert_Unpickle(SSMResource ** resource, 
  368.   SSMControlConnection * connection, 
  369.   PRInt32 len, 
  370.   void * value)
  371. {
  372.   SSMStatus rv = PR_SUCCESS;
  373.   SSMResourceID resID;
  374.   CERTCertificate * cert;
  375.   SECItem certArg;
  376.   if (!resource || !value) 
  377.      goto loser;
  378.   certArg.len = len;
  379.   certArg.data = (unsigned char *) value;
  380.   
  381.   cert = CERT_NewTempCertificate(connection->m_certdb,(SECItem *)&certArg, 
  382.                                  NULL, PR_FALSE, PR_TRUE);
  383.   if (!cert) {
  384.     rv = (SSMStatus) PR_GetError();
  385.     goto loser;
  386.   }
  387.   rv = SSM_CreateResource(SSM_RESTYPE_CERTIFICATE, (void *)cert, connection, 
  388.   &resID, resource); 
  389.   if (rv != PR_SUCCESS) goto loser;
  390.   goto done;
  391. loser:
  392.   if (resource && *resource) {
  393.     SSM_DEBUG("Error unpickling cert: %d.n", rv);
  394.     ((*resource)->m_destroy_func)(*resource, PR_TRUE);
  395.     PR_Free(*resource);
  396.   }
  397.   SSM_DEBUG("Error unpickling cert: %d.n", rv);
  398. done:
  399.   return rv;
  400. }
  401. SSMStatus SSMResourceCert_Destroy(SSMResource * resource, PRBool doFree)
  402. {
  403.   SSMResourceCert * res = (SSMResourceCert *)resource;
  404.   SSMResource *tmpRes;
  405.   if (!res) goto loser;
  406.   SSM_DEBUG("Trying to remove cert with id: %dn", resource->m_id);
  407.   /* remove cert from the cert resource db */
  408.   SSM_HashRemove(resource->m_connection->m_certIdDB, (SSMHashKey) res->cert, 
  409.    (void**)&tmpRes);
  410.   PR_ASSERT(tmpRes == resource); 
  411.   if (res->cert != NULL) {
  412.       if (res->m_markedForDeletion) {
  413.   SSM_DEBUG("Cert id %d is being deleted.n", resource->m_id);
  414.   if (SSMUI_CertBelongs(res->cert) == myCert) {
  415.       PK11_DeleteTokenCertAndKey(res->cert, res->super.m_connection);
  416.   }
  417.   else {
  418.       SEC_DeletePermCertificate(res->cert);
  419.   }
  420.       }
  421.       else {
  422.   CERT_DestroyCertificate(res->cert);
  423.       }
  424.       res->cert = NULL;
  425.   }
  426.   /* Destroy superclass */
  427.   SSMResource_Destroy(SSMRESOURCE(res), PR_FALSE);
  428.   
  429.   if (doFree)
  430.     PR_Free(res);
  431.   return PR_SUCCESS;
  432. loser:
  433.   return PR_FAILURE;
  434. }
  435. SSMStatus SSM_VerifyCert(SSMResourceCert * resource, 
  436. SECCertUsage certUsage)
  437. {
  438.   return (*resource->m_verify_func)(resource, certUsage);
  439. }
  440. SSMStatus SSM_DeleteCertificate(SSMResourceCert * resource) 
  441. {
  442.   return (*resource->m_deletecert_func)(resource);
  443. }
  444. SSMStatus SSMResourceCert_DeleteCert(SSMResourceCert * res)
  445. {
  446.   PR_ASSERT(SSM_IsAKindOf((SSMResource *)res, SSM_RESTYPE_CERTIFICATE));  
  447.   if (!res || !res->cert) {
  448.     SSM_DEBUG("DeleteCert: bad argument!n");
  449.     goto done;
  450.   }
  451.   SSM_DEBUG("Cert id %d is marked for deletion.n", ((SSMResource*)res)->m_id);
  452.   SSM_LockResource((SSMResource*)res);
  453.   res->m_markedForDeletion = PR_TRUE; /* delete it from disk */
  454.   SSM_UnlockResource((SSMResource*)res);
  455.   /* this will get the reference count right */
  456.   SSM_FreeResource((SSMResource*)res);
  457.  done:
  458.   return SSM_SUCCESS;
  459. }
  460. SSMStatus SSMResourceCert_Verify(SSMResourceCert  * resource,
  461. SECCertUsage certUsage)
  462. {
  463.   if (!resource || !resource->cert)
  464.     goto loser;
  465.   if (CERT_VerifyCertNow(SSMRESOURCE(resource)->m_connection->m_certdb, 
  466.  resource->cert, PR_TRUE, 
  467.  certUsage, 
  468.  SSMRESOURCE(resource)->m_connection) != SECSuccess) 
  469.     goto loser;
  470.   return PR_SUCCESS;
  471. loser:
  472.   return PR_FAILURE;
  473. }
  474. SSMStatus SSMResourceCert_HTML(SSMResource *res, PRIntn * len, void ** value)
  475. {
  476.   SSMStatus rv = PR_SUCCESS;
  477.   SSMResourceCert * resource = (SSMResourceCert *)res;
  478.   if (!resource || !resource->cert || !value) {
  479.     rv = (SSMStatus) PR_INVALID_ARGUMENT_ERROR;
  480.     goto loser;
  481.   }
  482.   *value = NULL;
  483.   if (len) *len = 0;
  484.     
  485.   *value = CERT_HTMLCertInfo(resource->cert, PR_FALSE, PR_TRUE);
  486.   if (!*value) { 
  487.     rv = (SSMStatus) PR_GetError();
  488.     goto loser;
  489.   }
  490.   
  491.   if (len)
  492.     *len = strlen((char *)*value);
  493.   goto done;
  494. loser:
  495.   if (len && *len) 
  496.     *len = 0;
  497.   if (value && *value) 
  498.     *value = NULL;
  499. done:
  500.   return rv;
  501. }
  502. SSMStatus
  503. SSM_CertRenewalHandler(HTTPRequest * req)
  504. {
  505. SSMResourceCert * target = (SSMResourceCert *)req->target;
  506. char * value;
  507. SSMStatus rv;
  508.   
  509. /* Renew cert action */
  510. rv = SSM_HTTPParamValue(req, "action", &value);
  511. if (rv != SSM_SUCCESS) 
  512. goto done;
  513. if (PL_strcmp(value, "now") == 0) {
  514. target->m_renewCert = PR_TRUE;
  515. } else {
  516. target->m_renewCert = PR_FALSE;
  517. }
  518. done:
  519. SSM_NotifyUIEvent((SSMResource *)target);
  520. return SSM_SUCCESS; 
  521. }
  522. SSMStatus
  523. SSMResourceCert_FormSubmitHandler(SSMResource *res, HTTPRequest * req)
  524. {
  525.   SSMStatus rv = SSM_FAILURE;
  526.   char* tmpStr = NULL;
  527.   
  528.   /* make sure you got the right baseRef */
  529.   rv = SSM_HTTPParamValue(req, "baseRef", &tmpStr);
  530.   if (rv != SSM_SUCCESS ||
  531.       PL_strcmp(tmpStr, "windowclose_doclose_js") != 0) {
  532.     goto loser;
  533.   }
  534.   
  535.   rv = SSM_HTTPCloseAndSleep(req);
  536.   if (rv != SSM_SUCCESS)
  537.     SSM_DEBUG("Errors closing window in FormSubmitHandler: %dn", rv);
  538.   
  539.   if (!res->m_formName)
  540.     goto loser;
  541.   if (PL_strcmp(res->m_formName, "cert_edit") == 0)
  542.     rv = SSM_EditCertificateTrustHandler(req);
  543.   else if (PL_strcmp(res->m_formName, "trust_new_ca") == 0)
  544.     rv = SSM_CertCAImportCommandHandler2(req);
  545.   else if (PL_strcmp(res->m_formName, "cert_renewal") == 0) {
  546. rv = SSM_CertRenewalHandler(req);
  547.   } else {
  548.     SSM_DEBUG("CertResource_FormsubmitHandler: bad formName %sn", res->m_formName);
  549.   }
  550.     
  551. loser:
  552.   return rv;
  553. }
  554. static
  555. certPane SSMUI_CertBelongs(CERTCertificate * cert)
  556. {
  557.   CERTCertTrust * trust;
  558.   certPane owner = badCert;
  559.   if (!cert || !cert->trust) 
  560.     goto done;
  561.   trust = cert->trust;
  562.   if ((trust->sslFlags & CERTDB_USER) ||
  563.       (trust->emailFlags & CERTDB_USER) ||
  564.       (trust->objectSigningFlags & CERTDB_USER))
  565.     owner = myCert;
  566.   else if ((trust->sslFlags & CERTDB_VALID_CA) ||
  567.    (trust->emailFlags & CERTDB_VALID_CA) ||
  568.    (trust->objectSigningFlags & CERTDB_VALID_CA))
  569.     owner = caCert;
  570.   else if (trust->sslFlags & CERTDB_VALID_PEER) 
  571.     owner = webCert;
  572.   else if (trust->emailFlags & CERTDB_VALID_PEER) 
  573.     owner = othersCert;
  574.  done:
  575.   return owner;
  576. }
  577. /* 
  578.  * Find correct help target for the kind of cert we're deleting.
  579.  */
  580. SSMStatus SSM_DeleteCertHelpKeywordHandler(SSMTextGenContext * cx)
  581. {
  582.   SSMStatus rv = SSM_FAILURE;
  583.   certPane kind = badCert;
  584.   PR_ASSERT(cx != NULL);
  585.   PR_ASSERT(cx->m_request != NULL);
  586.   PR_ASSERT(cx->m_params != NULL);
  587.   PR_ASSERT(cx->m_result != NULL);
  588.   PR_ASSERT(SSM_IsAKindOf(cx->m_request->target, SSM_RESTYPE_CERTIFICATE));
  589.   kind = SSMUI_CertBelongs(((SSMResourceCert *)cx->m_request->target)->cert);
  590.   switch (kind) {
  591.   case caCert:
  592.     rv = SSM_GetAndExpandText(cx, "help_delete_ca", &cx->m_result);
  593.     break;
  594.   case myCert:
  595.     rv = SSM_GetAndExpandText(cx, "help_delete_mine", &cx->m_result);
  596.     break;
  597.   case webCert:
  598.     rv = SSM_GetAndExpandText(cx, "help_delete_websites", &cx->m_result);
  599.     break;
  600.   case othersCert:
  601.     rv = SSM_GetAndExpandText(cx, "help_delete_others", &cx->m_result);
  602.     break;
  603.   default:
  604.     SSM_DEBUG("DeleteCertHelpKeyword: can't figure out cert type!n");
  605.   }
  606.   return rv;
  607. }
  608. SSMStatus SSM_DeleteCertWarnKeywordHandler(SSMTextGenContext * cx)
  609. {
  610.   SSMStatus rv = SSM_FAILURE;
  611.   certPane kind = badCert;
  612.   PR_ASSERT(cx != NULL);
  613.   PR_ASSERT(cx->m_request != NULL);
  614.   PR_ASSERT(cx->m_params != NULL);
  615.   PR_ASSERT(cx->m_result != NULL);
  616.   PR_ASSERT(SSM_IsAKindOf(cx->m_request->target, SSM_RESTYPE_CERTIFICATE));
  617.   kind = SSMUI_CertBelongs(((SSMResourceCert *)cx->m_request->target)->cert);
  618.   switch (kind)  {
  619.   case othersCert:
  620.     rv = SSM_GetAndExpandText(cx, "delete_cert_warning_others", &cx->m_result);
  621.     break;
  622.   case myCert:
  623.     rv = SSM_GetAndExpandText(cx, "delete_cert_warning_mine", &cx->m_result);
  624.     break;
  625.   case caCert:
  626.     rv = SSM_GetAndExpandText(cx, "delete_cert_warning_ca", &cx->m_result);
  627.     break;
  628.   case webCert:
  629.     rv = SSM_GetAndExpandText(cx, "delete_cert_warning_web", &cx->m_result);
  630.     break;
  631.   default:
  632.     SSM_DEBUG("DeleteCertWarnKeyword: can't figure out cert type!n");  
  633.   }
  634.   return rv;
  635. }
  636.   
  637. SSMStatus SSM_DeleteCertHandler(HTTPRequest * req)
  638. {
  639.   SSMStatus rv;
  640.   char * value = NULL;
  641.   char * nickname = NULL;
  642.   
  643.   /* if this brakes, we're in deep trouble */
  644.   PR_ASSERT(SSM_IsAKindOf(req->target, SSM_RESTYPE_CERTIFICATE));
  645.   /* close the window */
  646.   rv = SSM_HTTPCloseAndSleep(req);
  647.   if (rv != SSM_SUCCESS) 
  648.     SSM_DEBUG("DeleteCertHandler: Problem closing DeleteCertificateWindow!n");
  649.  
  650.   /* check which button was clicked */
  651.   rv = SSM_HTTPParamValue(req, "do_cancel", &value);
  652.   if (rv == SSM_SUCCESS) {
  653.     req->ctrlconn->super.super.m_buttonType = SSM_BUTTON_CANCEL;
  654.     goto done;
  655.   }
  656.   
  657.   rv = SSM_HTTPParamValue(req, "do_ok", &value);
  658.   if (rv == SSM_SUCCESS) {
  659.     if (((SSMResourceCert *)req->target)->cert->nickname)
  660.       nickname = PL_strdup(((SSMResourceCert *)req->target)->cert->nickname);
  661.     else nickname = PL_strdup(((SSMResourceCert *)req->target)->cert->emailAddr);
  662.     rv = (SSMStatus) SSM_DeleteCertificate((SSMResourceCert *)req->target);
  663.     /* delete this cert from Security Advisor hashtable */
  664.     rv = SSM_ChangeCertSecAdvisorList(req, nickname, (ssmCertHashAction)-1);
  665.     PR_Free(nickname);
  666.     goto done;
  667.   }
  668.   SSM_DEBUG("DeleteCertHandler: can't figure out which button was clicked in DeleteCert dialog!n");
  669.     
  670. done:
  671.   SSM_NotifyUIEvent(&req->ctrlconn->super.super);
  672.   return rv;
  673. }
  674. SSMStatus SSM_ProcessCertDeleteButton(HTTPRequest * req)
  675. {
  676.   SSMResource * target;
  677.   char * params = NULL;
  678.   char * certNickname = NULL, * formName = NULL;
  679.   char * page = NULL, * outPage = NULL;
  680.   SSMStatus rv = SSM_FAILURE;
  681.   rv = SSM_HTTPParamValue(req, "selectCert", &certNickname);
  682.   if (rv != SSM_SUCCESS) 
  683.     goto loser;
  684.   
  685.   rv = SSM_HTTPParamValue(req, "formName", &formName);
  686.   if (rv != SSM_SUCCESS) 
  687.     goto loser;
  688.   
  689.   /* Get the target resource. */
  690.   target = (req->target ? req->target : (SSMResource *) req->ctrlconn);
  691.   PR_ASSERT(target);
  692.   
  693.   params = PR_smprintf("action=delete_cert&nick=%s&formName=%s",certNickname, 
  694.        formName);
  695.   SSM_LockUIEvent(&req->ctrlconn->super.super);
  696.   rv = SSMControlConnection_SendUIEvent(req->ctrlconn, "cert", "delete_cert", 
  697. target, params, 
  698. &target->m_clientContext, PR_TRUE);
  699.   SSM_WaitUIEvent(&req->ctrlconn->super.super, PR_INTERVAL_NO_TIMEOUT);
  700.   /* See if the user canceled, if so send back HTTP_NO_CONTENT
  701.    * so security advisor doesn't redraw the same content.
  702.    */
  703.   if (req->ctrlconn->super.super.m_buttonType == SSM_BUTTON_CANCEL) {
  704.     SSM_HTTPReportError(req, HTTP_NO_CONTENT);
  705.     goto done;
  706.   }  
  707.  /* tell the secadvisor page to reload */
  708.   rv = SSM_RefreshRefererPage(req);
  709.   goto done;
  710.   
  711. loser:
  712.   if (rv == SSM_SUCCESS) 
  713.     rv = SSM_FAILURE;
  714.   SSM_HTTPReportSpecificError(req, 
  715.       "ProcessDeleteCert: can't send/process delete cert UIEvent", rv);
  716. done:
  717.   PR_FREEIF(params);
  718.   PR_FREEIF(page);
  719.   PR_FREEIF(outPage);
  720.   return rv;
  721. }
  722. SSMStatus SSM_RefreshRefererPage(HTTPRequest * req)
  723. {
  724.   SSMTextGenContext * cx = NULL;
  725.   SSMStatus rv = SSM_FAILURE;
  726.   char * page = NULL, * outPage = NULL, * ptr = NULL;
  727.   if (!req) 
  728.     goto done;
  729.   
  730.   /* ptr will point the last '/' in the referer URL. We are interested 
  731.    * in everything AFTER the last '/'.
  732.    */
  733.   ptr = strrchr(req->referer, '/');
  734.   
  735.   rv = SSMTextGen_NewTopLevelContext(req, &cx);
  736.   rv = SSM_GetAndExpandText(cx, "refresh_window_content", &page);
  737.   SSMTextGen_DestroyContext(cx);
  738.   outPage = PR_smprintf(page, ptr+1);
  739.   req->sentResponse = PR_TRUE;
  740.   rv = SSM_HTTPSendOKHeader(req, NULL, "text/html");
  741.   rv = SSM_HTTPSendUTF8String(req, outPage);
  742.  done:
  743.   return rv;
  744. }
  745. SSMStatus SSM_HTTPCertListHandler(HTTPRequest * req)
  746. {
  747.   SSMStatus rv = SSM_FAILURE;
  748.   char * nick = NULL, * action = NULL, *target, * page=NULL, *outPage = NULL;
  749.   char * nickhtml = NULL, * formName = NULL;
  750.   CERTCertificate * cert;
  751.   CERTCertList * certList = NULL;
  752.   SSMTextGenContext * cx; 
  753.   PRBool emailCert = PR_FALSE;
  754.   char * certres;
  755.   SSMResource * certresource;
  756.   SSMResourceCert * certRes;
  757.   SSM_DEBUG("In cert_list handlern");
  758.   /* figure out the certificate  */
  759.   /* this is a cert identified by resource id */
  760.   rv = SSM_HTTPParamValue(req, "certresource", &certres);
  761.   if (rv == SSM_SUCCESS) {
  762.     rv = SSM_RIDTextToResource(req, certres, &certresource);
  763.     if (rv != SSM_SUCCESS || !certresource 
  764. || !(SSM_IsAKindOf(certresource, SSM_RESTYPE_CERTIFICATE))) {
  765.       SSM_DEBUG("certListHandler:can't find cert by resource ID %s!n", certres);
  766.   goto loser;
  767. }
  768.     certRes = ((SSMResourceCert *)certresource);
  769.     rv = SSM_ProcessCertResourceUIAction(req, certRes);
  770.     goto done;
  771.   }
  772.   rv = SSM_HTTPParamValue(req, "target", &target);
  773.   if (rv != SSM_SUCCESS) 
  774.     /* can't find target */
  775.     goto loser;
  776.   
  777.   rv = SSM_HTTPParamValue(req, "nick", &nick);
  778.   if (rv != SSM_SUCCESS || PL_strcmp(nick,"undefined")==0) {
  779.     /* can't find cert selection */
  780.     SSM_DEBUG("certListHandler: can't find cert nick!n");
  781.     goto loser;
  782.   }
  783.   nickhtml = SSM_ConvertStringToHTMLString(nick);
  784.   if (!nickhtml) {
  785.     SSM_DEBUG("HTTPCertListHandler: error in ConvertStringToHTMLStringn");
  786.     goto loser;
  787.   }
  788.   rv = SSM_HTTPParamValue(req, "formName", &formName);
  789.   if (rv != SSM_SUCCESS || !formName) {
  790.     SSM_DEBUG("certListHandler: no originating formName found!n");
  791.     goto loser;
  792.   }
  793.   
  794.   /* look for certs by nickname, unless it's "others", 
  795.    * then check email address
  796.    */
  797.   if (strstr(formName,"_others")) 
  798.     emailCert = PR_TRUE;
  799.   certList = SSMControlConnection_CreateCertListByNickname(req->ctrlconn, 
  800.    nick, 
  801.    emailCert);
  802.   if (certList && SSM_CertListCount(certList) > 1)
  803.     { /* more than one cert under the same nickname */
  804.              
  805.       /* get current values */
  806.       rv = SSM_HTTPParamValue(req, "action", &action);
  807.       if (rv != SSM_SUCCESS) {
  808. /* can't find action selection */
  809. goto loser;
  810.       }
  811.       rv = SSMTextGen_NewTopLevelContext(req, &cx);
  812.       rv = SSM_GetAndExpandText(cx, "choose_cert_content", &page);
  813.       SSMTextGen_DestroyContext(cx);
  814.       outPage = PR_smprintf(page, atoi(target), action, nickhtml, formName);
  815.       rv = SSM_HTTPSendOKHeader(req, NULL, "text/html");
  816.       rv = SSM_HTTPSendUTF8String(req, outPage);
  817.       
  818.     }
  819.   else 
  820.     {
  821.       /* get selected certificate */
  822.       cert = SSMControlConnection_FindCertByNickname(req->ctrlconn, nick, 
  823.      emailCert);
  824.       if (!cert) {
  825. SSM_DEBUG("HTTPCertListHandler: can't find cert with nick %s!n",nick);
  826. goto loser;
  827.       }
  828.       rv = SSM_ProcessCertUIAction(req, cert);
  829.     }  
  830. done:
  831.   PR_FREEIF(page);
  832.   PR_FREEIF(outPage);
  833.   PR_FREEIF(nickhtml);
  834.   if (certList) 
  835.     CERT_DestroyCertList(certList);
  836.  
  837.   return rv;
  838. loser:
  839.   if (certList) 
  840.     CERT_DestroyCertList(certList);
  841.   
  842.   /* kill the window */
  843.   rv = SSMTextGen_NewTopLevelContext(req, &cx);
  844.   rv = SSM_GetAndExpandText(cx, "windowclose_doclose_js_content", &page);
  845.   SSMTextGen_DestroyContext(cx);
  846.   req->sentResponse = PR_TRUE;
  847.   rv = SSM_HTTPSendOKHeader(req, NULL, "text/html");
  848.   rv = SSM_HTTPSendUTF8String(req, page);
  849.   /* notify owner if this a UI event */
  850.   if (((SSMResource *)req->ctrlconn)->m_UILock) 
  851.     SSM_NotifyUIEvent((SSMResource *)req->ctrlconn);
  852.   
  853.   return SSM_SUCCESS;
  854. }
  855. SSMStatus SSM_ProcessCertResourceUIAction(HTTPRequest * req, 
  856.   SSMResourceCert * certres)
  857. {
  858.   SSMResourceID resID;
  859.   SSMStatus rv = SSM_FAILURE;
  860.   char * page = NULL, *outPage = NULL;
  861.   char * action, *ref;
  862.   SSMTextGenContext * cx = NULL;
  863.   /* Free reference to the previous target
  864.    */
  865.   if (req->target) {
  866.     SSM_FreeResource(req->target);
  867.   }
  868.   req->target = &certres->super;
  869.   /*
  870.    * Sigh, this is so hacked up that the only way I can prevent a crash now
  871.    * is to get an extra reference here so the target doesn't disappear.
  872.    * -javi
  873.    */
  874.   SSM_GetResourceReference(req->target);
  875.   resID = certres->super.m_id;
  876.   /* figure out what action was requested */
  877.   rv = SSM_HTTPParamValue(req, "action", &action);
  878.   if (rv != SSM_SUCCESS) {
  879.     SSM_DEBUG("ProcessCertUIAction: no action parameter found!n");
  880.     SSM_HTTPReportError(req, HTTP_NO_CONTENT);
  881.     goto done;
  882.   }
  883.   ref = PR_smprintf("%s_content", action);
  884.   rv = SSMTextGen_NewTopLevelContext(req, &cx);
  885.   if (rv != SSM_SUCCESS) 
  886.     SSM_DEBUG("ProcessUIAction: can't get new TopLevelContextn");
  887.   rv = SSM_GetAndExpandText(cx, ref, &page);
  888.   if (rv != SSM_SUCCESS) 
  889.     SSM_DEBUG("ProcessUIAction:can't get wrapper for %sn", action);
  890.   SSMTextGen_DestroyContext(cx);
  891.   outPage = PR_smprintf(page, resID, action, "bogus");
  892.   rv = SSM_HTTPSendOKHeader(req, NULL, "text/html");
  893.   rv = SSM_HTTPSendUTF8String(req, outPage);
  894.  done:
  895.   PR_FREEIF(page);
  896.   PR_FREEIF(outPage);
  897.   return rv;
  898. }    
  899. SSMStatus
  900. SSM_ProcessCertUIAction(HTTPRequest * req, CERTCertificate * cert)
  901. {
  902.   SSMResourceCert * certres = NULL;
  903.   SSMStatus rv;
  904.   SSMResourceID resID;
  905.   if (!cert) {
  906.     SSM_DEBUG("ProcessCertUIAction: no cert. Either user hit Cancel or smth is wrong.n");
  907.     SSM_DEBUG("Close the window n");    
  908.     goto done;
  909.   }
  910.   /* get a resource for this cert */
  911.   rv = (SSMStatus) SSM_CreateResource(SSM_RESTYPE_CERTIFICATE, (void *)cert, 
  912.   req->ctrlconn, &resID, (SSMResource**)&certres); 
  913.   if (rv != SSM_SUCCESS) 
  914.     goto done;  
  915.   /*
  916.    * XXX This is a gross hack.  But, iff the previous target was another
  917.    *     certificate, release the reference so that reference counts will
  918.    *     stay in sync.
  919.    */
  920.   if (SSM_IsAKindOf(req->target, SSM_RESTYPE_CERTIFICATE)) {
  921.     SSM_FreeResource(req->target);
  922.   }
  923.   return SSM_ProcessCertResourceUIAction(req, certres);
  924.  done:
  925.   return rv;
  926. }
  927. char * digits = "0123456789ABCDEF";
  928. #define HEX_DIGIT(x)  (strchr(digits, *x) - digits)
  929. SECItem *
  930. unhexify(char * hex) 
  931. {
  932.   SECItem * result = NULL;
  933.   char * data = NULL;
  934.   char * ptr, *ch;
  935.   PRIntn len;
  936.   
  937.   if (!hex)
  938.     return NULL;
  939.   result = (SECItem *) PORT_ZAlloc(sizeof(SECItem));
  940.   ch = hex;
  941.   len = strlen(hex)/2;
  942.   if (strlen(hex)&1) 
  943.     len++;
  944.   ptr = data = (char *) PORT_ZAlloc(len);
  945.   if (strlen(hex)&1) {
  946.     *ptr = HEX_DIGIT(ch);
  947.     ptr++;
  948.     ch++;
  949.   }
  950.   while (*ch) { 
  951.     *ptr = (HEX_DIGIT(ch) << 4) + HEX_DIGIT((ch+1));
  952.     ch += 2;
  953.     ptr++;
  954.   }
  955.   result->data = (unsigned char *) data;
  956.   result->len = len;
  957.   return result;
  958. }
  959.  
  960. /*
  961.  * Here's how we do unhexify -jp
  962.  * Number[J]=HexDigit(*P)*16+HexDigit(*(P+1));
  963.  * J++;
  964.  * P+=2;
  965.  * char *Digits="012345679ABCDEF"
  966.  *return(strchr(Digits,toupper(Char))-Digits)
  967.  */ 
  968. SSMStatus SSM_ChooseCertUsageHandler(HTTPRequest * req)
  969. {
  970.   SSMResource * target = NULL, *origTarget;
  971.   char * value = NULL, * nick = NULL, *serialNum;
  972.   char * tmp;
  973.   SSMStatus rv = SSM_FAILURE;
  974.   SECItem * keyID;
  975.   CERTCertificate * cert = NULL;
  976.   SSMTextGenContext * cx;
  977.   char * urlStr=NULL, *action=NULL, * redirectHTML=NULL, * outStr=NULL;
  978.   SSMResourceID resID;
  979.   char * windowName = NULL, * params = NULL;
  980.   /* Get the target resource. */
  981.   target = (req->target ? req->target : (SSMResource *) req->ctrlconn);
  982.   PR_ASSERT(target);
  983.   origTarget = target;
  984.   rv = SSM_HTTPParamValue(req, "selectItem", &value);
  985.   if (rv != SSM_SUCCESS) 
  986.     goto loser;
  987.   rv = SSM_HTTPParamValue(req, "nick", &nick);
  988.   if (rv != SSM_SUCCESS)
  989.     goto loser;
  990.   
  991.   rv = SSM_HTTPParamValue(req, "baseRef", &action);
  992.   if (rv != SSM_SUCCESS)
  993.     goto loser;
  994.   
  995.   tmp = PL_strdup(value);
  996.   value = strtok(tmp, ":");
  997.   serialNum = strtok(NULL, ":");
  998.   keyID = unhexify(value);
  999.   cert = FindCertByKeyIDAndNickname(req->ctrlconn, nick, keyID, serialNum);
  1000.   SECITEM_FreeItem(keyID,PR_TRUE);
  1001.   PR_Free(tmp);
  1002.   
  1003.   SSM_DEBUG("ChooseCertUsageHandler: found certificate %lx!n", cert);
  1004.   req->ctrlconn->super.super.m_uiData = (void *)cert;
  1005.   
  1006.   /* set the window name:
  1007.    * View is done through http thread, window name is popup
  1008.    * Delete is done with UIEvent, window name is PSM
  1009.    */
  1010.   if (PL_strcmp(action, "cert_view") == 0 || 
  1011.       PL_strcmp(action, "ca_policy_view") == 0) 
  1012.     windowName = PR_smprintf("popup");
  1013.   else if (PL_strcmp(action, "delete_cert") == 0)
  1014.     windowName = PR_smprintf("PSM");
  1015.   else if (PL_strcmp(action, "backup") == 0)
  1016.     windowName = NULL;
  1017.   else if (PL_strcmp(action, "cert_edit") == 0)
  1018.     windowName = PR_smprintf("popup");
  1019.   else {
  1020.     SSM_DEBUG("ChooseCertUsageHandler: bad action baseRef = %s", action);
  1021.     goto loser;
  1022.   }
  1023.   
  1024.   /* make sure the next URL takes up the whole window */
  1025.   rv = SSMTextGen_NewTopLevelContext(req, &cx);
  1026.   if (rv != SSM_SUCCESS) {
  1027.     SSM_DEBUG("ChooseCertUsageHandler: can't get new textGen contextn");
  1028.     goto loser;
  1029.   }
  1030.   rv = (SSMStatus) SSM_CreateResource(SSM_RESTYPE_CERTIFICATE, (void *)cert, 
  1031.   req->ctrlconn, &resID, &target);
  1032.   if (rv != SSM_SUCCESS) {
  1033.     SSM_DEBUG("ChooseCertUsageHandler: can't create cert resource n");
  1034.     goto loser;
  1035.   }
  1036.   if (!MIN_STRCMP(action, "backup")) {
  1037.     rv = SSM_GetAndExpandText(cx, "windowclose_doclose_js_content", &outStr);
  1038.     if (rv != SSM_SUCCESS) {
  1039.       goto loser;
  1040.     }
  1041.     SSM_NotifyUIEvent(origTarget);
  1042.   } else {
  1043.     /* policy view requires extra parameters */
  1044.     if (PL_strcmp(action, "ca_policy_view") == 0)
  1045.       params = PR_smprintf("&certresource=%d&bogus=bogus", resID);
  1046.     
  1047.     urlStr = PR_smprintf("get?baseRef=%s&target=%d%s", action, resID, params?params:"");
  1048.  
  1049.     rv = SSM_GetAndExpandText(cx, "refresh_frameset_content", &redirectHTML);
  1050.     if (rv != SSM_SUCCESS)
  1051.       SSM_DEBUG("ChooseCertUsageHandler: can't create redirectHTML");
  1052.     outStr = PR_smprintf(redirectHTML, urlStr, windowName);
  1053.     SSMTextGen_DestroyContext(cx);
  1054.     cx = NULL;
  1055.     PR_Free(urlStr);
  1056.     PR_Free(redirectHTML);
  1057.   }
  1058.   req->sentResponse = PR_TRUE;
  1059.   rv = SSM_HTTPSendOKHeader(req, NULL, "text/html");
  1060.   if (rv != SSM_SUCCESS) 
  1061.     SSM_DEBUG("ChooseCertUsageHandler: error sending OKHeadersn");
  1062.   rv = SSM_HTTPSendUTF8String(req, outStr);
  1063.   if (rv != SSM_SUCCESS)
  1064.     SSM_DEBUG("ChooseCertUsageHandler: error sending <%s>n", outStr);
  1065.   PR_FREEIF(windowName);
  1066.   PR_Free(outStr);
  1067.   if (cx != NULL)
  1068.     SSMTextGen_DestroyContext(cx);
  1069.   return rv;
  1070. loser:  
  1071.   if (cx != NULL)
  1072.     SSMTextGen_DestroyContext(cx);
  1073.   if (rv == SSM_SUCCESS)
  1074.     rv = SSM_FAILURE;
  1075.   SSM_DEBUG("ChooseCertUsageHandler: somethings is very wrong!n");
  1076.   return SSM_HTTPCloseWindow(req);
  1077.  }
  1078. CERTCertificate *
  1079. FindCertByKeyIDAndNickname(SSMControlConnection * ctrl, char *nickname, 
  1080.    SECItem *keyID, char * serial)
  1081. {
  1082.   CERTCertificate *cert = NULL;
  1083.   CERTCertList *certList = NULL;
  1084.   CERTCertListNode *node;
  1085.   char *hexSerial=NULL;
  1086.   certList = SSMControlConnection_CreateCertListByNickname(ctrl, nickname, 
  1087.    PR_FALSE);
  1088.   if (!certList)  /* could not find certs with this nick, try email address */
  1089.     certList = SSMControlConnection_CreateCertListByNickname(ctrl, nickname, 
  1090.      PR_TRUE);  
  1091.   if (!certList) 
  1092.     goto loser;
  1093.   node = CERT_LIST_HEAD(certList);
  1094.   while (!CERT_LIST_END(node, certList)) {
  1095.     if (cert_GetKeyID(node->cert) != SECSuccess) 
  1096.       goto loser;
  1097.     hexSerial = CERT_Hexify(&node->cert->serialNumber, 0);
  1098.     if ( SECITEM_CompareItem(keyID, &node->cert->subjectKeyID) == SECEqual &&
  1099.  (hexSerial == NULL ||  
  1100.   strcmp(hexSerial, serial) == 0)) { 
  1101.       PR_FREEIF(hexSerial);   
  1102.       goto found;
  1103.     }
  1104.     PR_FREEIF(hexSerial);
  1105.     node = CERT_LIST_NEXT(node);
  1106.   }
  1107.   
  1108.   SSM_DEBUG("FindCertByKeyIDAndNickname: could not find certificate!n");
  1109.   goto loser;
  1110. found:
  1111.   cert = CERT_DupCertificate(node->cert);
  1112. loser:
  1113.   if (certList) 
  1114.     CERT_DestroyCertList(certList);
  1115.   return cert;
  1116. }
  1117. static SSMStatus
  1118. SSM_DoOCSPError(SSMTextGenContext *cx, CERTCertificate *cert,
  1119. const char* textKey)
  1120. {
  1121.     SSMStatus rv;
  1122.     char *tmp=NULL, *url=NULL;
  1123.     rv = SSM_GetAndExpandText(cx, textKey, &tmp);
  1124.     if (rv == SSM_SUCCESS) {
  1125.         PR_FREEIF(cx->m_result);
  1126.         url = SSM_GetOCSPURL(cert, cx->m_request->target->m_connection->m_prefs);
  1127.         PR_ASSERT(url != NULL);
  1128. cx->m_result = PR_smprintf(tmp, url);
  1129.         PR_Free(url); 
  1130.     }
  1131.     PR_FREEIF(tmp);
  1132.     return rv;
  1133. }
  1134. static SSMStatus
  1135. SSM_BuildErrorMessage(SSMTextGenContext *cx, SSMResourceCert *certres)
  1136. {
  1137.     PRErrorCode err;
  1138.     SECCertUsage certUsage;
  1139.     SSMStatus rv;
  1140.     if (ssm_cert_belongs_type(certres->cert, USER_CERT) == SSM_SUCCESS) {
  1141.       certUsage = certUsageEmailRecipient;
  1142.     } else 
  1143.     if (ssm_cert_belongs_type(certres->cert, EMAIL_CERT) == SSM_SUCCESS) {
  1144.       certUsage = certUsageEmailRecipient;
  1145.     } else 
  1146.     if (ssm_cert_belongs_type(certres->cert, CA_CERT) == SSM_SUCCESS) {
  1147.       certUsage = certUsageSSLCA;
  1148.     } else 
  1149.     if (ssm_cert_belongs_type(certres->cert, WEBSITE_CERT) == SSM_SUCCESS) {
  1150.       certUsage = certUsageSSLServer;
  1151.     }
  1152.     
  1153.     if (SSM_VerifyCert(certres, certUsage) != SECSuccess) {
  1154.       err = PR_GetError();
  1155.       switch (err) {
  1156.       case SEC_ERROR_EXPIRED_CERTIFICATE:
  1157. rv = SSM_GetAndExpandText(cx, "not_verified_expired_cert_text", 
  1158.   &cx->m_result);
  1159. break;
  1160.       case SEC_ERROR_REVOKED_CERTIFICATE:
  1161. rv = SSM_GetAndExpandText(cx, "not_verified_revoked_cert_text", 
  1162.   &cx->m_result);
  1163. break;
  1164.       case SEC_ERROR_UNKNOWN_ISSUER:
  1165. rv = SSM_GetAndExpandText(cx, "not_verified_unknown_issuer_text", 
  1166.   &cx->m_result);
  1167. break;
  1168.       case SEC_ERROR_CA_CERT_INVALID:
  1169. rv = SSM_GetAndExpandText(cx, "not_verified_ca_invalid_text", 
  1170.   &cx->m_result);
  1171. break;
  1172.       case SEC_ERROR_UNTRUSTED_ISSUER:
  1173. rv = SSM_GetAndExpandText(cx, "not_verified_untrusted_issuer_text", 
  1174.   &cx->m_result);
  1175. break;
  1176.       case SEC_ERROR_EXPIRED_ISSUER_CERTIFICATE:
  1177. rv = SSM_GetAndExpandText(cx, "not_verified_expired_issuer_text", 
  1178.   &cx->m_result);
  1179. break;
  1180.       case SEC_ERROR_UNTRUSTED_CERT:
  1181. rv = SSM_GetAndExpandText(cx, "not_verified_untrusted_cert_text", 
  1182.   &cx->m_result);
  1183. break;
  1184.       case SEC_ERROR_CERT_BAD_ACCESS_LOCATION:
  1185. rv = SSM_DoOCSPError(cx, certres->cert, "not_verified_bad_ocsp_url");
  1186. break;
  1187.       case SEC_ERROR_OCSP_UNKNOWN_RESPONSE_TYPE:
  1188. rv = SSM_DoOCSPError(cx, certres->cert, 
  1189.      "not_verified_unknown_ocsp_response_type");
  1190. break;
  1191.       case SEC_ERROR_OCSP_BAD_HTTP_RESPONSE:
  1192. rv = SSM_DoOCSPError(cx, certres->cert,
  1193.      "bad_ocsp_http_response");
  1194. break;
  1195.       case SEC_ERROR_OCSP_SERVER_ERROR:
  1196. rv = SSM_DoOCSPError(cx, certres->cert, "ocsp_server_error");
  1197. break;
  1198.       case SEC_ERROR_OCSP_MALFORMED_REQUEST:
  1199. rv = SSM_DoOCSPError(cx, certres->cert, "bad_ocsp_der");
  1200. break;
  1201.       case SEC_ERROR_OCSP_UNAUTHORIZED_RESPONSE:
  1202. rv = SSM_DoOCSPError(cx, certres->cert, "ocsp_unauthorized_responder");
  1203. break;
  1204.       case SEC_ERROR_OCSP_TRY_SERVER_LATER:
  1205. rv = SSM_DoOCSPError(cx, certres->cert, "ocsp_try_server_later");
  1206. break;
  1207.       case SEC_ERROR_OCSP_REQUEST_NEEDS_SIG:
  1208. rv = SSM_DoOCSPError(cx, certres->cert, "ocsp_response_needs_sig");
  1209. break;
  1210.       case SEC_ERROR_OCSP_UNAUTHORIZED_REQUEST:
  1211. rv = SSM_DoOCSPError(cx, certres->cert, "ocsp_unauthorized_request");
  1212. break;
  1213.       case SEC_ERROR_OCSP_UNKNOWN_RESPONSE_STATUS:
  1214. rv = SSM_DoOCSPError(cx, certres->cert, "ocsp_unknown_status");
  1215. break;
  1216.       case SEC_ERROR_OCSP_UNKNOWN_CERT:
  1217. rv = SSM_DoOCSPError(cx, certres->cert, "ocsp_unknown_cert");
  1218. break;
  1219.       case SEC_ERROR_OCSP_NOT_ENABLED:
  1220. rv = SSM_DoOCSPError(cx, certres->cert, "ocsp_not_enabled");
  1221. break;
  1222.       case SEC_ERROR_OCSP_NO_DEFAULT_RESPONDER:
  1223. rv = SSM_DoOCSPError(cx, certres->cert, "ocsp_no_default_responder");
  1224. break;
  1225.       case SEC_ERROR_OCSP_MALFORMED_RESPONSE:
  1226. rv = SSM_DoOCSPError(cx, certres->cert, "ocsp_malformed_response");
  1227. break;
  1228.       case SEC_ERROR_OCSP_FUTURE_RESPONSE:
  1229. rv = SSM_DoOCSPError(cx, certres->cert, "ocsp_future_response");
  1230. break;
  1231.       case SEC_ERROR_OCSP_OLD_RESPONSE:
  1232. rv = SSM_DoOCSPError(cx, certres->cert, "ocsp_old_response");
  1233. break;
  1234.       case PR_DIRECTORY_LOOKUP_ERROR:
  1235. /* Add some extra logic because NSS doesn't always set error 
  1236.  * codes for OCSP failures.
  1237.  */
  1238. if (SSM_IsOCSPEnabled(certres->super.m_connection)) {
  1239.     rv = SSM_DoOCSPError(cx, certres->cert, 
  1240.  "not_verified_bad_ocsp_url");
  1241.     break;
  1242. }
  1243.       default:
  1244. rv = SSM_GetAndExpandText(cx, "not_verified_unknown_error_text", 
  1245.   &cx->m_result);
  1246.       }
  1247.     } else {
  1248.       rv = SSM_GetAndExpandText(cx, "not_verified_unknown_error_text", 
  1249. &cx->m_result);
  1250.     }
  1251.     return rv;
  1252. }
  1253. SSMStatus
  1254. SSM_VerifyCertKeywordHandler(SSMTextGenContext * cx)
  1255. {
  1256.   SSMStatus rv = SSM_FAILURE;
  1257.   SSMResourceCert * certres = NULL;
  1258.   /* All the certUsage values currently defined in NSS */
  1259.   /* All of these strings should come from the properties files. */
  1260.   char * formatKey = NULL, * fmt = NULL;
  1261.   PRBool verified[12];
  1262.   char * result = NULL;
  1263.   PRInt32 i, j;
  1264.   PRBool valid = PR_FALSE;
  1265.   PR_ASSERT(cx != NULL);
  1266.   PR_ASSERT(cx->m_request != NULL);
  1267.   PR_ASSERT(cx->m_params != NULL);
  1268.   PR_ASSERT(cx->m_result != NULL);
  1269.   PR_ASSERT(SSM_IsAKindOf(cx->m_request->target, SSM_RESTYPE_CERTIFICATE));
  1270.   /* get certificate resource */
  1271.   certres = (SSMResourceCert *)cx->m_request->target;
  1272.   for (i = 0, j= 0; i < certUsageAnyCA + 1; i++) {
  1273.     /* UserCertImport, ProtectedObjectSigner, AnyCA, VerifyCA certUsages 
  1274.      * cause NSS to panic, make sure we don't try to verify it.
  1275.      */
  1276.     if (i == certUsageUserCertImport ||
  1277. i == certUsageProtectedObjectSigner ||
  1278. i == certUsageVerifyCA ||
  1279. i == certUsageAnyCA) {
  1280.       verified[i] = PR_FALSE;
  1281.       continue;
  1282.     }
  1283.     if (SSM_VerifyCert(certres, (SECCertUsage) i) == SECSuccess) {
  1284.       verified[i] = PR_TRUE;
  1285.       valid = PR_TRUE;
  1286.     }
  1287.     else verified[i] = PR_FALSE;
  1288.   }
  1289.   
  1290.   if (valid) {
  1291.     rv = SSM_GetAndExpandText(cx, "verified_prefix", 
  1292.       &cx->m_result);
  1293.   } else {
  1294.     rv = SSM_BuildErrorMessage(cx, certres);
  1295.   }
  1296.   formatKey = (char *) SSM_At(cx->m_params, (PRIntn)0);
  1297.   rv = SSM_GetAndExpandTextKeyedByString(cx, formatKey, &fmt);
  1298.   if (rv != SSM_SUCCESS) 
  1299.     goto loser;
  1300.   result = PR_smprintf(fmt, verified[0], verified[1], verified[2],
  1301.        verified[3], verified[4], verified[5],
  1302.        verified[6], verified[7], verified[8],
  1303.        verified[9], verified[10], verified[11], valid);
  1304.   rv = SSM_ConcatenateUTF8String(&cx->m_result, result);
  1305.   PR_Free(result);
  1306.   rv = SSM_SUCCESS;
  1307.   goto done;
  1308.   
  1309.  loser:
  1310.   SSM_DEBUG("VerifyCertKeywordHandler: something is wrong!n");
  1311.   if (rv == SSM_SUCCESS) 
  1312.     rv = SSM_FAILURE;
  1313.   if (cx->m_result) 
  1314.     PR_Free(cx->m_result);
  1315.   cx->m_result = NULL;
  1316.  done:
  1317.   PR_FREEIF(fmt);
  1318.   return rv;
  1319. }
  1320. SSMStatus 
  1321. SSM_EditCertKeywordHandler(SSMTextGenContext * cx)
  1322. {
  1323.   SSMStatus rv;
  1324.   SSMResourceCert * target = (SSMResourceCert *)SSMTextGen_GetTargetObject(cx);
  1325.   CERTCertTrust * trust;
  1326.   char * tmpStr = NULL, *checked = NULL, *notAvailable = NULL, * donot= NULL;
  1327.   PRBool trusted=PR_FALSE, trustca = PR_FALSE;
  1328.   PRBool emailtrust=PR_FALSE, signtrust=PR_FALSE, ssltrust = PR_FALSE; 
  1329. /* edit cert dialog help targets */
  1330.   char * emailCertHelpTarget = "1036027";
  1331.   char * sslCertHelpTarget   = "1035916";
  1332.   char * caCertHelpTarget    = "1036857";
  1333.  
  1334.   PR_ASSERT(target && SSM_IsAKindOf((SSMResource *)target, SSM_RESTYPE_CERTIFICATE));
  1335.   PR_ASSERT(target->cert);
  1336.   
  1337.   rv = SSM_GetAndExpandTextKeyedByString(cx, "text_checked", &checked);
  1338.   if (rv != SSM_SUCCESS) {
  1339.     SSM_DEBUG("EditCertKeywordHandler: can't get text for 'checked'n");
  1340.     goto done;
  1341.   }
  1342.   rv = SSM_GetAndExpandTextKeyedByString(cx, "trust_do_not", &donot);
  1343.   if (rv != SSM_SUCCESS) {
  1344.     SSM_DEBUG("EditCertKeywordHandler: can't get text for 'trust_do_not'n");
  1345.     goto done;
  1346.   }
  1347.   
  1348.   rv = SSM_GetAndExpandTextKeyedByString(cx, "text_not_available", 
  1349.  &notAvailable);
  1350.   if (rv != SSM_SUCCESS) {
  1351.     SSM_DEBUG("EditCertKeywordHandler: can't get text for notAvailablen");
  1352.     goto done;
  1353.   }
  1354.   if ((trust = target->cert->trust) == NULL) {
  1355.     SSM_DEBUG("EditCertKeywordHandler: cert trust object is NULL!n");
  1356.     rv = SSM_FAILURE;
  1357.     goto done;
  1358.   }
  1359.   
  1360.   /* website cert */
  1361.   if (trust->sslFlags & CERTDB_VALID_PEER) { 
  1362.     CERTCertificate * issuer = CERT_FindCertIssuer(target->cert, PR_Now(), 
  1363.  certUsageAnyCA);
  1364.     if (issuer && issuer->trust && 
  1365. (issuer->trust->sslFlags & CERTDB_TRUSTED_CA))
  1366.       trustca = PR_TRUE;
  1367.     rv = SSM_GetAndExpandTextKeyedByString(cx, "edit_cert_website", &tmpStr);
  1368.     if (rv != SSM_SUCCESS) {
  1369.       SSM_DEBUG("EditCertKeywordHandler: can't find edit_cert_website n");
  1370.       goto done;
  1371.     }
  1372.     /* check first button if trusted, second if not */
  1373.     if (trust->sslFlags & CERTDB_TRUSTED)
  1374.       trusted = PR_TRUE;
  1375.     PR_FREEIF(cx->m_result); 
  1376.     cx->m_result = PR_smprintf(tmpStr, target->cert->nickname, 
  1377.        CERT_GetCommonName(&target->cert->issuer),
  1378.        issuer?issuer->nickname:notAvailable,
  1379.        trusted?checked:"", 
  1380.        trusted?"":checked,
  1381.        sslCertHelpTarget,
  1382.        trustca?"":donot,
  1383.        trustca?"":donot);
  1384.     
  1385.   } else if ( (trust->sslFlags & CERTDB_VALID_CA)    ||
  1386.       (trust->emailFlags & CERTDB_VALID_CA ) ||
  1387.       ( trust->objectSigningFlags & CERTDB_VALID_CA )) {
  1388.  
  1389.    /* security advisor in 4.x does this, should we? */
  1390.     if ( ! ( target->cert->nsCertType & NS_CERT_TYPE_CA ) ) 
  1391.       target->cert->nsCertType = NS_CERT_TYPE_CA;
  1392.     
  1393.     rv = SSM_GetAndExpandTextKeyedByString(cx, "edit_cert_authority", &tmpStr);
  1394.     if (rv != SSM_SUCCESS) {
  1395.       SSM_DEBUG("EditCertKeywordHandler: can't get edit_cert_authority wrappern");
  1396.       goto done;
  1397.     }
  1398.     
  1399.     /* check first button if trusted, second if not */
  1400.     if (trust->sslFlags & CERTDB_TRUSTED_CA)
  1401.       ssltrust = PR_TRUE;
  1402.     if (trust->emailFlags & CERTDB_TRUSTED_CA)
  1403.       emailtrust = PR_TRUE;
  1404.     if (trust->objectSigningFlags & CERTDB_TRUSTED_CA ) 
  1405.       signtrust = PR_TRUE;
  1406.     
  1407.     PR_FREEIF(cx->m_result);
  1408.     cx->m_result = PR_smprintf(tmpStr, ssltrust?checked:"", 
  1409.        emailtrust?checked:"",
  1410.        signtrust?checked:"", 
  1411.        target->cert->nickname,
  1412.        caCertHelpTarget);
  1413.   } else if (trust->emailFlags & CERTDB_VALID_PEER) {
  1414.     CERTCertificate * issuer = CERT_FindCertIssuer(target->cert, PR_Now(), 
  1415.  certUsageAnyCA);
  1416.     char *CN = NULL;
  1417.     if (issuer && issuer->trust && 
  1418. (issuer->trust->emailFlags & CERTDB_TRUSTED_CA))
  1419.       trustca = PR_TRUE;
  1420.     rv = SSM_GetAndExpandTextKeyedByString(cx, "edit_cert_others", &tmpStr);
  1421.     if (rv != SSM_SUCCESS) {
  1422.       SSM_DEBUG("EditCertKeywordHandler: can't get edit_cert_authority wrappern");
  1423.       goto done;
  1424.     }
  1425.     if (trust->emailFlags & CERTDB_TRUSTED) 
  1426.       trusted = PR_TRUE;
  1427.     PR_FREEIF(cx->m_result);
  1428.     CN = CERT_GetCommonName(&target->cert->issuer);
  1429.     cx->m_result = PR_smprintf(tmpStr, target->cert->emailAddr, 
  1430.        CN,
  1431.        issuer?issuer->nickname:notAvailable,
  1432.        trusted?checked:"", 
  1433.        trusted?"":checked,
  1434.        emailCertHelpTarget,
  1435.        trustca?"":donot,
  1436.        trustca?"":donot);
  1437.     PR_FREEIF(CN);
  1438.   } else {
  1439.     PR_FREEIF(cx->m_result);
  1440.     cx->m_result = PR_smprintf("Bad certificate type, don't know how to edit.n");
  1441.   }
  1442.     
  1443. done:
  1444.   PR_FREEIF(tmpStr);
  1445.   PR_FREEIF(checked);
  1446.   PR_FREEIF(donot);
  1447.   return rv;
  1448. }
  1449. SSMStatus
  1450. SSM_EditCertificateTrustHandler(HTTPRequest * req)
  1451. {
  1452.   SSMResourceCert * target = (SSMResourceCert *)req->target;
  1453.   CERTCertTrust trust; 
  1454.   char * value;
  1455.   SSMStatus rv;
  1456.   
  1457.   PR_ASSERT(target && target->cert);
  1458.   rv = (SSMStatus) CERT_GetCertTrust(target->cert, &trust);
  1459.   if (rv != SSM_SUCCESS) {
  1460.     SSM_DEBUG("EditCertificateTrustHandler: can't get cert trust objectn");
  1461.     goto done;
  1462.   }
  1463.   
  1464.   if (trust.sslFlags & CERTDB_VALID_PEER) {
  1465.     /* this is website cert we're editing */
  1466.     rv = SSM_HTTPParamValue(req, "trustoption", &value);
  1467.     if (rv != SSM_SUCCESS) 
  1468.       goto done;
  1469.     if (strcmp(value, "trust") == 0)
  1470.       trust.sslFlags |= CERTDB_TRUSTED;
  1471.     else trust.sslFlags &= (~CERTDB_TRUSTED);
  1472.   } 
  1473.   else 
  1474.     if ( (trust.sslFlags & CERTDB_VALID_CA)    ||
  1475.  (trust.emailFlags & CERTDB_VALID_CA ) ||
  1476.  ( trust.objectSigningFlags & CERTDB_VALID_CA ) 
  1477.  ) {
  1478.       /* security advisor in 4.x does this, should we? */
  1479.       if ( ! ( target->cert->nsCertType & NS_CERT_TYPE_CA ) ) 
  1480. target->cert->nsCertType = NS_CERT_TYPE_CA;
  1481.       
  1482.       if (target->cert->nsCertType & NS_CERT_TYPE_SSL_CA)
  1483. trust.sslFlags |= CERTDB_VALID_CA;
  1484.       if (target->cert->nsCertType & NS_CERT_TYPE_OBJECT_SIGNING_CA)
  1485. trust.objectSigningFlags |= CERTDB_VALID_CA;
  1486.       if (target->cert->nsCertType & NS_CERT_TYPE_EMAIL_CA)
  1487. trust.emailFlags |= CERTDB_VALID_CA;
  1488.       rv = SSM_HTTPParamValue(req, "networksite", &value);
  1489.       if (rv == SSM_SUCCESS) 
  1490. trust.sslFlags |= CERTDB_TRUSTED_CA;
  1491.       else trust.sslFlags &= (~CERTDB_TRUSTED_CA);
  1492.       
  1493.       rv = SSM_HTTPParamValue(req, "emailuser", &value);
  1494.       if (rv == SSM_SUCCESS) 
  1495. trust.emailFlags |= CERTDB_TRUSTED_CA;
  1496.       else trust.emailFlags &= (~CERTDB_TRUSTED_CA);
  1497.       
  1498.       rv = SSM_HTTPParamValue(req, "software", &value);
  1499.       if (rv == SSM_SUCCESS) 
  1500. trust.objectSigningFlags |= CERTDB_TRUSTED_CA;
  1501.       else trust.objectSigningFlags &= (~CERTDB_TRUSTED_CA);
  1502.     }
  1503.   else if (trust.emailFlags & CERTDB_VALID_PEER) 
  1504.     { 
  1505.       /* edit email cert */
  1506.       rv = SSM_HTTPParamValue(req, "trustoption", &value);
  1507.       if (rv != SSM_SUCCESS) 
  1508. goto done;
  1509.       if (PL_strcmp(value, "trust") == 0)
  1510. trust.emailFlags |= CERTDB_TRUSTED;
  1511.       else trust.emailFlags &= (~CERTDB_TRUSTED);
  1512.     }
  1513.   else 
  1514.     {
  1515.       SSM_DEBUG("EditCertificateTrustHandler: trying to edit bad certn");
  1516.       goto done;
  1517.     }
  1518.    rv = (SSMStatus) CERT_ChangeCertTrust(req->ctrlconn->m_certdb, target->cert, &trust);
  1519.    SSL_ClearSessionCache();
  1520. done:
  1521.    return SSM_SUCCESS; 
  1522. }
  1523. SSMStatus
  1524. SSM_SelectCertKeywordHandler(SSMTextGenContext * cx)
  1525. {
  1526.   SSMStatus rv = SSM_SUCCESS;
  1527.   char * value = NULL, *formName = NULL;
  1528.   char * fmt = NULL;
  1529.   PRIntn PARAM_FORMAT = (PRIntn) 0;
  1530.   PRIntn certType, certKey;
  1531.   /* Check for parameter validity */
  1532.   PR_ASSERT(cx);
  1533.   PR_ASSERT(cx->m_request);
  1534.   PR_ASSERT(cx->m_params);
  1535.   PR_ASSERT(cx->m_result);
  1536.   if (!cx || !cx->m_request || !cx->m_params || !cx->m_result)
  1537.     {
  1538.       rv = (SSMStatus) PR_INVALID_ARGUMENT_ERROR;
  1539.       goto loser; 
  1540.     }
  1541.   rv = SSM_HTTPParamValue(cx->m_request, "origin", &formName);
  1542.   if (rv != SSM_SUCCESS)
  1543.     goto loser;
  1544.   
  1545.   /* figure which certs we're looking for */
  1546.   if (strstr(formName, "_mine")) {
  1547.     certType = USER_CERT;
  1548.     certKey = NICKNAME;
  1549.   } else if (strstr(formName, "_others")) {
  1550.     certType = EMAIL_CERT;
  1551.     certKey = EMAILADDR;
  1552.   } else if (strstr(formName, "_websites")) {
  1553.     certType = WEBSITE_CERT;
  1554.     certKey = NICKNAME;
  1555.   } else if (strstr(formName, "_authorities")) {
  1556.     certType = CA_CERT;
  1557.     certKey = NICKNAME;
  1558.   } else 
  1559.     SSM_DEBUG("SelectCertKeywordHandler: Bad requestn");
  1560.   
  1561.   /* get format */
  1562.   fmt = (char *) SSM_At(cx->m_params, PARAM_FORMAT);
  1563.   rv = SSM_HTTPParamValue(cx->m_request, "content", &value);
  1564.   if (!fmt || !value) {
  1565.     SSM_DEBUG("SelectCertKeywordHandler: can't get format or nickname!n");
  1566.     goto loser;
  1567.   }
  1568.   rv = SSM_GetAndExpandTextKeyedByString(cx, fmt, &fmt);
  1569.   if (rv != SSM_SUCCESS) 
  1570.     goto loser;
  1571.   SSM_DebugUTF8String("cert selection format <%s>", fmt);
  1572.   
  1573.   rv = ssm_select_cert(cx, &cx->m_result, fmt, certType, certKey, value);
  1574.   goto done;
  1575.   
  1576. loser:
  1577.   PR_FREEIF(cx->m_result);
  1578.   cx->m_result = NULL;
  1579.   if (rv == SSM_SUCCESS) 
  1580.     rv = SSM_FAILURE;
  1581. done:  
  1582.   return rv;
  1583. }
  1584. SSMStatus
  1585. ssm_select_cert(SSMTextGenContext * cx, char ** result, char * fmt, 
  1586. PRIntn type, PRIntn key,char *nickname) 
  1587. {
  1588.   CERTCertList * certList;
  1589.   CERTCertListNode * node;
  1590.   CERTCertificate * cert;
  1591.   char * tmpStr = NULL, * checked = NULL;
  1592.   SSMStatus rv = SSM_FAILURE;
  1593.   PRBool first = PR_TRUE;
  1594.   
  1595.   PR_ASSERT(result);
  1596.   PR_ASSERT(fmt);
  1597.   PR_ASSERT(nickname);
  1598.   
  1599.   if (!result || !fmt || !nickname) {
  1600.     SSM_DEBUG("Bad parameters in ssm_select_cert_nickn");
  1601.     goto loser;
  1602.   }
  1603.   *result = NULL;
  1604.  
  1605.   /* get a list of certs with the given nick or email address*/
  1606.   switch (key) {
  1607.   case NICKNAME:
  1608.     certList = SSMControlConnection_CreateCertListByNickname(cx->m_request->ctrlconn, 
  1609.      nickname, 
  1610.      PR_FALSE);
  1611.     break;
  1612.   case EMAILADDR:
  1613.     certList = SSMControlConnection_CreateCertListByNickname(cx->m_request->ctrlconn, nickname, 
  1614.      PR_TRUE);
  1615.     break;
  1616.   default:
  1617.     SSM_DEBUG("select_cert: bad cert key, must be NICKNAME or EMAILADDRn");
  1618.     goto loser;
  1619.   }
  1620.   if (!certList) {
  1621.     SSM_DEBUG("select_cert: no certificate with nick %s in the dbn", 
  1622.       nickname);
  1623.     goto done;
  1624.   }
  1625.   rv = SSM_GetAndExpandTextKeyedByString(cx, "text_checked", &checked);
  1626.   if (rv != SSM_SUCCESS) {
  1627.     SSM_DEBUG("select_cert: can't get text for checked attributen");
  1628.     goto done;
  1629.   }
  1630.   /* traverse the list */
  1631.   node = CERT_LIST_HEAD(certList);
  1632.   while (!CERT_LIST_END(node, certList))
  1633.     {
  1634.       cert = node->cert;
  1635.       node = CERT_LIST_NEXT(node);
  1636.       /* make sure it's correct type of cert */
  1637.       if (ssm_cert_belongs_type(cert, type) != SSM_SUCCESS) 
  1638. continue;
  1639.       
  1640.       rv = ssm_create_select_cert_entry(cx, cert, &tmpStr, fmt, first?checked:""); 
  1641.       if (rv != SSM_SUCCESS) { 
  1642. SSM_DEBUG("Could not create select_cert_entryn");
  1643. goto loser;
  1644.       }
  1645.       rv = SSM_ConcatenateUTF8String(result, tmpStr);
  1646.       if (rv != SSM_SUCCESS)
  1647. goto loser;
  1648.       PR_Free(tmpStr);
  1649.       tmpStr = NULL;
  1650.       first = PR_FALSE;
  1651.     }/* end of loop on certs in the certList */
  1652.   goto done;
  1653.   
  1654. loser:
  1655.   if (rv == SSM_SUCCESS)
  1656.     rv = SSM_FAILURE;
  1657.   if (result && *result)
  1658.     PR_Free(*result);
  1659.   *result = NULL;
  1660.   
  1661. done:
  1662.   if (certList)
  1663.     CERT_DestroyCertList(certList);
  1664.   if (tmpStr) 
  1665.     PR_Free(tmpStr);
  1666.   return rv;
  1667. }
  1668. SSMStatus
  1669. ssm_create_select_cert_entry(SSMTextGenContext * cx, CERTCertificate * cert, 
  1670.      char **result, char *fmt, char *checked) 
  1671.   {
  1672.     char * validNotBefore = NULL, * validNotAfter = NULL;
  1673.     char * purposeStr = NULL;
  1674.     char * valueStr = NULL, * serialNum = NULL;
  1675.     SSMStatus rv = SSM_FAILURE;
  1676.     
  1677.     PR_ASSERT(result);
  1678.     PR_ASSERT(fmt);
  1679.     PR_ASSERT(cert);
  1680.     if (!result || !fmt || !cert) {
  1681.       SSM_DEBUG("Bad params in ssm_create_select_cert_entry!n");
  1682.       return SSM_FAILURE;
  1683.     }
  1684.     *result = NULL;
  1685.     /* now find info about this certificate */
  1686.     validNotBefore = DER_UTCDayToAscii(&cert->validity.notBefore);
  1687.     validNotAfter = DER_UTCDayToAscii(&cert->validity.notAfter);
  1688.     
  1689.     if ((cert->keyUsage & KU_KEY_ENCIPHERMENT) == KU_KEY_ENCIPHERMENT) 
  1690.       SSM_GetUTF8Text(cx, "key_encipherment", &purposeStr);
  1691.     else if ((cert->keyUsage & KU_DIGITAL_SIGNATURE) == KU_DIGITAL_SIGNATURE)
  1692.       SSM_GetUTF8Text(cx, "digital_signature", &purposeStr);
  1693.     else if ((cert->keyUsage & KU_KEY_AGREEMENT) == KU_KEY_AGREEMENT) 
  1694.       SSM_GetUTF8Text(cx, "key_agreement", &purposeStr);
  1695.     else {
  1696.       SSM_DEBUG("Can't find certificate usage!n");
  1697.       goto loser;
  1698.     }
  1699.     rv = (SSMStatus) cert_GetKeyID(cert);
  1700.     if (rv != SECSuccess) 
  1701.       goto loser;
  1702.     valueStr = PR_smprintf("%s", CERT_Hexify(&(cert->subjectKeyID),
  1703.      PR_FALSE));
  1704.     serialNum = CERT_Hexify(&cert->serialNumber, 0);
  1705.     if (!serialNum) 
  1706.       serialNum = PL_strdup("--");
  1707.     /* string ? 
  1708.      * <input type="radio" name="selectItem" value=keyusage> keyusage, etc.
  1709.      */
  1710.     *result = PR_smprintf(fmt, valueStr, purposeStr, validNotBefore, 
  1711.   validNotAfter, checked, serialNum);
  1712.     goto done;
  1713.   loser:
  1714.     if (*result)
  1715.       PR_Free(result);
  1716.     *result = NULL;
  1717.   done:
  1718.     if (purposeStr) 
  1719.       PR_Free(purposeStr);
  1720.     if (valueStr)
  1721.       PR_Free(valueStr);
  1722.     if (validNotBefore)
  1723.       PR_Free(validNotBefore);
  1724.     if (validNotAfter)
  1725.       PR_Free(validNotAfter);
  1726.     PR_FREEIF(serialNum);
  1727.     return rv;
  1728.   }
  1729. SSMStatus
  1730. ssm_cert_belongs_type(CERTCertificate * cert, PRIntn type)
  1731.   {
  1732.     PR_ASSERT(cert);
  1733.     /* cert is not in perm database */
  1734.     if (!cert->trust) 
  1735.       goto loser;
  1736.     switch (type) {
  1737.     case USER_CERT:
  1738.       if ((cert->trust->sslFlags & CERTDB_USER) ||
  1739.   (cert->trust->emailFlags & CERTDB_USER) ||
  1740.   (cert->trust->objectSigningFlags & CERTDB_USER) )
  1741.         goto done;
  1742.       break;
  1743.     case EMAIL_CERT:
  1744.       if (cert->emailAddr && 
  1745.   (ssm_cert_belongs_type(cert, USER_CERT) != SSM_SUCCESS ) &&
  1746.   (cert->trust->emailFlags & CERTDB_VALID_PEER))
  1747. goto done;
  1748.       break;
  1749.     case WEBSITE_CERT:
  1750.       if (cert->trust->sslFlags & CERTDB_VALID_PEER) 
  1751. goto done;
  1752.       break;
  1753.     case CA_CERT:
  1754.       if ((cert->trust->sslFlags & CERTDB_VALID_CA) ||
  1755.   (cert->trust->emailFlags & CERTDB_VALID_CA) ||
  1756.   (cert->trust->objectSigningFlags & CERTDB_VALID_CA)) {
  1757. /* it is a CA cert, make sure it's not invisible cert */
  1758. if (!((cert->trust->sslFlags & CERTDB_INVISIBLE_CA) ||
  1759.       (cert->trust->emailFlags & CERTDB_INVISIBLE_CA) || 
  1760.       (cert->trust->objectSigningFlags & CERTDB_INVISIBLE_CA)))
  1761.   goto done;
  1762.       }
  1763.       break;
  1764.     default:
  1765.       PR_ASSERT(0);
  1766.     }
  1767.     goto loser;
  1768. done:  
  1769.     return SSM_SUCCESS;
  1770. loser: 
  1771.     return SSM_FAILURE;
  1772.   }
  1773. SSMStatus
  1774. SSM_ViewCertInfoKeywordHandler(SSMTextGenContext * cx)
  1775. {
  1776.   SSMStatus rv = SSM_FAILURE;
  1777.   char* pattern = NULL;
  1778.   char* key = NULL;
  1779.   char * style = NULL, *commentString = NULL;
  1780.   const PRIntn CERT_WRAPPER = (PRIntn)1;
  1781.   const PRIntn CERT_WRAPPER_NO_COMMENT = (PRIntn)2;
  1782.   const PRIntn STYLE_PARAM = (PRIntn)0;
  1783.   PRIntn wrapper;
  1784.   CERTCertificate * cert = NULL;
  1785.   PR_ASSERT(cx != NULL);
  1786.   PR_ASSERT(cx->m_request != NULL);
  1787.   PR_ASSERT(cx->m_params != NULL);
  1788.   PR_ASSERT(cx->m_result != NULL);
  1789.   PR_ASSERT(SSM_IsAKindOf(cx->m_request->target, SSM_RESTYPE_CERTIFICATE));
  1790.  
  1791.   if (cx == NULL || cx->m_request == NULL || cx->m_params == NULL ||
  1792.       cx->m_result == NULL) {
  1793.     PR_SetError(PR_INVALID_ARGUMENT_ERROR, 0);
  1794.     goto loser;
  1795.   }
  1796.   /* get cert */
  1797.   cert = ((SSMResourceCert *)cx->m_request->target)->cert;
  1798.   if (!cert)
  1799.     goto loser;
  1800.   /* get the correct wrapper */
  1801.   commentString = CERT_GetCertCommentString(cert);
  1802.   if (commentString)
  1803.     wrapper = CERT_WRAPPER;
  1804.   else wrapper = CERT_WRAPPER_NO_COMMENT;
  1805.   key = (char *) SSM_At(cx->m_params, wrapper);
  1806.   PR_FREEIF(commentString);
  1807.   
  1808.   /* second, grab and expand the keyword objects */
  1809.   rv = SSM_GetAndExpandTextKeyedByString(cx, key, &pattern);
  1810.   if (rv != SSM_SUCCESS) {
  1811.     goto loser;
  1812.   }
  1813.   SSM_DebugUTF8String("ca cert info pattern <%s>", pattern);
  1814.   
  1815.   style = (char *) SSM_At(cx->m_params, STYLE_PARAM);
  1816.   PR_FREEIF(cx->m_result);
  1817.   if (!strcmp(style, "pretty")) 
  1818.     rv = SSM_PrettyFormatCert(cert, pattern, &cx->m_result, PR_TRUE);
  1819.   else
  1820.     rv = SSM_FormatCert(cert, pattern, &cx->m_result);
  1821.   goto done;
  1822.  loser:
  1823.   if (rv == SSM_SUCCESS)
  1824.     rv = SSM_FAILURE;
  1825.  done:
  1826.   PR_FREEIF(pattern);
  1827.   return rv;
  1828. }
  1829. int
  1830. SSM_CertListCount(CERTCertList *certList)
  1831. {
  1832.   int numCerts = 0;
  1833.   CERTCertListNode *node;
  1834.   
  1835.   node = CERT_LIST_HEAD(certList);
  1836.   while (!CERT_LIST_END(node, certList)) {
  1837.     numCerts++;
  1838.     node = CERT_LIST_NEXT(node);
  1839.   }
  1840.   return numCerts;
  1841. }
  1842. /* ### mwelch - PKCS11 private function? Need prototype for Mac */
  1843. #ifdef XP_MAC
  1844. CERTCertList *
  1845. PK11_FindCertsFromNickname(char *nickname, void *wincx);
  1846. #endif
  1847. CERTCertList * 
  1848. SSMControlConnection_CreateCertListByNickname(SSMControlConnection * ctrl, 
  1849.       char * nick, PRBool email)
  1850. {
  1851.   CERTCertList * certListDB = NULL, * certListExternal = NULL;
  1852.   certListDB = CERT_NewCertList();
  1853.   if (email) 
  1854.     certListDB = CERT_CreateEmailAddrCertList(certListDB,ctrl->m_certdb,
  1855.     nick, PR_Now(), PR_FALSE);
  1856.   else 
  1857.     certListDB = CERT_CreateNicknameCertList(certListDB, ctrl->m_certdb,
  1858.      nick, PR_Now(), PR_FALSE);
  1859.   if (!certListDB && !email) 
  1860.     certListExternal = PK11_FindCertsFromNickname(nick, ctrl);
  1861.   if (certListExternal) 
  1862.     return certListExternal;
  1863.   else 
  1864.     return certListDB;
  1865. }
  1866.       
  1867. CERTCertificate * 
  1868. SSMControlConnection_FindCertByNickname(SSMControlConnection * ctrl, 
  1869. char * nick, PRBool email)
  1870. {
  1871.   CERTCertificate * cert = NULL;
  1872.   
  1873.   if (email) 
  1874.     cert = CERT_FindCertByEmailAddr(ctrl->m_certdb, nick);
  1875.   else 
  1876.     cert = CERT_FindCertByNickname(ctrl->m_certdb, nick);
  1877.   if (!cert && !email) 
  1878.     cert = PK11_FindCertFromNickname(nick, ctrl);
  1879.   return cert;
  1880. }
  1881. SSMStatus
  1882. SSM_OCSPOptionsKeywordHandler(SSMTextGenContext *cx)
  1883. {
  1884.   SSMStatus rv;
  1885.   PRBool prefBool;
  1886.   char *fmt = NULL, *ocspURL;
  1887.   char *noOCSP = NULL, *noDefaultResponder = NULL, *useDefaultResponder = NULL;
  1888.   PrefSet *prefs;
  1889.   rv =  SSM_GetAndExpandTextKeyedByString(cx, "ocsp_options_template",
  1890.   &fmt);
  1891.   if (rv != SSM_SUCCESS) {
  1892.     goto loser;
  1893.   }
  1894.   prefs = cx->m_request->ctrlconn->m_prefs;
  1895.   rv = PREF_GetStringPref(prefs, "security.OCSP.URL", &ocspURL);
  1896.   if (rv != SSM_SUCCESS) {
  1897.     ocspURL = "";
  1898.   }
  1899.   rv = PREF_GetBoolPref(prefs, "security.OCSP.enabled", &prefBool);
  1900.   /*
  1901.    * Since the CHECKED is part of the HTML parsed by the broswer,
  1902.    * We don't have to localize it.  If the user were going to see
  1903.    * it, then we would have to localize it.
  1904.    */
  1905.   if (rv != SSM_SUCCESS || !prefBool) {
  1906.     noOCSP              = "CHECKED";
  1907.     noDefaultResponder  = "";
  1908.     useDefaultResponder = "";
  1909.   } else {
  1910.     rv = PREF_GetBoolPref(prefs, "security.OCSP.useDefaultResponder", 
  1911.   &prefBool);
  1912.     if (rv != SSM_SUCCESS) {
  1913.       noOCSP              = "CHECKED";
  1914.       noDefaultResponder  = "";
  1915.       useDefaultResponder = "";
  1916.     } else if (prefBool) {
  1917.       noOCSP              = "";
  1918.       noDefaultResponder  = "";
  1919.       useDefaultResponder = "CHECKED";
  1920.     } else {
  1921.       noOCSP              = "";
  1922.       noDefaultResponder  = "CHECKED";
  1923.       useDefaultResponder = "";
  1924.     }
  1925.   }
  1926.   PR_FREEIF(cx->m_result);
  1927.   cx->m_result = PR_smprintf(fmt, noOCSP,noDefaultResponder,
  1928.      useDefaultResponder, ocspURL);
  1929.   PR_Free(fmt);
  1930.   return SSM_SUCCESS;
  1931.  loser:
  1932.   PR_FREEIF(fmt);
  1933.   return SSM_FAILURE;
  1934. }
  1935. SSMStatus
  1936. SSM_OCSPDefaultResponderKeywordHandler(SSMTextGenContext *cx)
  1937. {
  1938.   SSMStatus rv;
  1939.   char *defaultResponder = NULL, *fmt = NULL;
  1940.   
  1941.   rv = PREF_GetStringPref(cx->m_request->ctrlconn->m_prefs, 
  1942.   "security.OCSP.signingCA",
  1943.   &defaultResponder);
  1944.   if (rv != SSM_SUCCESS) {
  1945.     goto loser;
  1946.   } 
  1947.   rv = SSM_GetAndExpandTextKeyedByString(cx, "default_responder_template", 
  1948.  &fmt);
  1949.   if (rv != SSM_SUCCESS) {
  1950.     goto loser;
  1951.   }
  1952.   PR_FREEIF(cx->m_result);
  1953.   cx->m_result = PR_smprintf(fmt, defaultResponder);
  1954.   if (cx->m_result == NULL) {
  1955.     goto loser;
  1956.   }
  1957.   PR_Free(fmt);
  1958.   return SSM_SUCCESS;
  1959.   
  1960.  loser:
  1961.   cx->m_result = PL_strdup("");
  1962.   PR_FREEIF(fmt);
  1963.   return SSM_SUCCESS;
  1964. }
  1965. SSMStatus 
  1966. SSM_ObtainNewCertSite(SSMTextGenContext * cx)
  1967. {
  1968.   char * newCertURL = NULL;
  1969.   SSMStatus rv = SSM_FAILURE;
  1970.   rv = PREF_GetStringPref(cx->m_request->ctrlconn->m_prefs, "obtainCertURL",
  1971.   &newCertURL);
  1972.   if (rv == SSM_SUCCESS) 
  1973.     goto done;
  1974.   rv = SSM_GetAndExpandText(cx, "new_cert_URL", &newCertURL);
  1975.   if (rv != SSM_SUCCESS) {
  1976.     SSM_DEBUG("NewCertSite: can't find URL for obtaining new certs!n");
  1977.     goto loser;
  1978.   }
  1979.   SSM_DEBUG("NewCertSite: no customized URL provided using default:%s", 
  1980.     newCertURL);
  1981.   
  1982.  done:
  1983.   PR_FREEIF(cx->m_result);
  1984.   cx->m_result = newCertURL;
  1985.   newCertURL = NULL;
  1986.  loser:
  1987.   return rv;
  1988. }
  1989. SSMStatus SSM_ProcessLDAPWindow(HTTPRequest * req)
  1990. {
  1991.   SSMStatus rv = SSM_FAILURE;
  1992.   SSMResource * target = NULL;
  1993.   char **ldap_servers, **ptr, *params = NULL;
  1994.   SSMHTTPParamMultValues emailAddresses={NULL, NULL, 0};
  1995.   int i;
  1996.   if (!req || !req->ctrlconn) 
  1997.     goto loser;
  1998.   rv = PREF_CreateChildList(req->ctrlconn->m_prefs, 
  1999.     "ldap_2.servers", &ldap_servers);
  2000.   if (rv != SSM_SUCCESS || !ldap_servers) {
  2001.     SSMControlConnection_SendUIEvent(req->ctrlconn, "get", 
  2002.                                      "show_followup", NULL, 
  2003.      "result=no_ldap_setup", 
  2004.                                      &((SSMResource *)req->ctrlconn)->m_clientContext,
  2005.      PR_TRUE);
  2006.     goto loser;
  2007.   }
  2008.     
  2009.   target = (req->target ? req->target : (SSMResource *) req->ctrlconn);
  2010.   /*
  2011.    * Let's see if there were some email addresses passed along to this
  2012.    * dialog that we should pre-fill the window with.
  2013.    */
  2014.   rv  = SSM_HTTPParamValueMultiple(req, "emailAddresses", &emailAddresses);
  2015.   if (rv == SSM_SUCCESS && emailAddresses.numValues > 0) {
  2016.     char *tmp;
  2017.     /* There are some email addresses that need to be passed on. */
  2018.     for (i=0; i<emailAddresses.numValues; i++) {
  2019.       tmp = PR_smprintf("%s%s%s", (params)?params:"", (params)?",":"",
  2020.            emailAddresses.values[i]);
  2021.       PR_FREEIF(params);
  2022.       params = tmp;
  2023.     }
  2024.     tmp = SSM_ConvertStringToHTMLString(params);
  2025.     PR_Free(params);
  2026.     params = PR_smprintf("emailAddresses=%s", tmp);
  2027.     PR_Free(tmp);
  2028.   }
  2029.   /* send UI event to bring up the dialog */
  2030.   SSM_LockUIEvent(target);
  2031.   rv = SSMControlConnection_SendUIEvent(req->ctrlconn, "get", 
  2032. "ldap_request", target, 
  2033. params, &target->m_clientContext, 
  2034. PR_TRUE);
  2035.   if (rv != SSM_SUCCESS) { 
  2036.     SSM_UnlockUIEvent(target);
  2037.     goto loser;
  2038.   }
  2039.   SSM_WaitUIEvent(target, PR_INTERVAL_NO_TIMEOUT);
  2040.   /*  if (req->ctrlconn->super.super.m_buttonType == SSM_BUTTON_CANCEL) {
  2041.       SSM_HTTPReportError(req, HTTP_NO_CONTENT);
  2042.       goto loser;
  2043.       }
  2044.   */
  2045.   /* free memory from ChildList */
  2046.   ptr = ldap_servers;
  2047.   while (*ptr) { 
  2048.     PR_Free(*ptr);
  2049.     ptr++;
  2050.   }
  2051.   PR_Free(ldap_servers);
  2052.   
  2053.  loser:
  2054.   if (req) {
  2055.     if (req->target->m_buttonType == SSM_BUTTON_CANCEL) {
  2056.       SSM_HTTPReportError(req, HTTP_NO_CONTENT);
  2057.     } else {
  2058.       SSM_RefreshRefererPage(req);
  2059.     }
  2060.   }
  2061.   /* Don't free the values stored in the individual array because
  2062.    * those are owned by the request structure.
  2063.    */
  2064.   PR_FREEIF(emailAddresses.values);
  2065.   return rv;
  2066. }
  2067. SSMStatus SSM_ProcessLDAPRequestHandler(HTTPRequest * req)
  2068. {
  2069.   SSMStatus rv = SSM_FAILURE;
  2070.   char * tmpStr = NULL, *emailaddr, *ldapserver;
  2071.   char* key = NULL, *currEmail, *cursor;
  2072.   PRBool updateList = PR_FALSE;
  2073.   /* make sure you got the right baseRef */
  2074.   rv = SSM_HTTPParamValue(req, "baseRef", &tmpStr);
  2075.   if (rv != SSM_SUCCESS ||
  2076.       PL_strcmp(tmpStr, "windowclose_doclose_js") != 0) {
  2077.     goto loser;
  2078.   }
  2079.   /* Close the window */
  2080.   rv = SSM_HTTPDefaultCommandHandler(req);
  2081.   if (rv != SSM_SUCCESS) 
  2082.     SSM_DEBUG("UI_ProcessLDAPRequest: can't close the window !n");
  2083.   rv = SSM_HTTPParamValue(req, "do_cancel", &tmpStr);
  2084.   if (rv == SSM_SUCCESS && tmpStr) {
  2085.     req->target->m_buttonType = SSM_BUTTON_CANCEL;
  2086.     goto loser;
  2087.   }
  2088.   req->target->m_buttonType = SSM_BUTTON_OK;
  2089.   rv = SSM_HTTPParamValue(req, "emailaddress", &emailaddr);
  2090.   if (rv != SSM_SUCCESS) {
  2091.     SSM_DEBUG("UI_ProcessLDAPRequest: no email address supplied!n");
  2092.     goto loser;
  2093.   }
  2094.   rv = SSM_HTTPParamValue(req, "ldapServer", &ldapserver);
  2095.   if (rv != SSM_SUCCESS) {
  2096.     SSM_DEBUG("UI_ProcessLDAPRequest: can't find ldap server parameter!n");
  2097.     goto loser;
  2098.   }
  2099.   
  2100.   /* create a complete key part */
  2101.   key = PR_smprintf("ldap_2.servers.%s", ldapserver);
  2102.   if (key == NULL) {
  2103.       goto loser;
  2104.   }
  2105.   /*
  2106.    * Now let's loop over the each entry looking for the certs.
  2107.    */
  2108.   cursor = currEmail = emailaddr;
  2109.   while (cursor != NULL && *cursor != '') {
  2110.     char oldCursorVal;
  2111.     cursor = PL_strpbrk(currEmail, " ,");
  2112.     if (cursor != NULL) {
  2113.       oldCursorVal = *cursor;
  2114.       *cursor = '';
  2115.     }
  2116.     rv = SSM_CompleteLDAPLookup(req->ctrlconn, key, currEmail);
  2117.     if (rv == SSM_SUCCESS) {
  2118.       updateList = PR_TRUE;
  2119.     }
  2120.     if (cursor != NULL) {
  2121.       *cursor = oldCursorVal;
  2122.       cursor++;
  2123.     }
  2124.     /*
  2125.      * Jump over all of the white space and commas.
  2126.      */
  2127.     while (cursor && *cursor && isspace(*cursor))
  2128.       cursor++;
  2129.     while (cursor && *cursor == ',') {
  2130.       cursor++;
  2131.       while (cursor && *cursor && isspace(*cursor))
  2132. cursor++;
  2133.     }
  2134.     currEmail = cursor;
  2135.   }
  2136.   if (updateList) 
  2137.     SSM_ChangeCertSecAdvisorList(req, emailaddr, certHashAdd);
  2138.   else 
  2139.     SSM_DEBUG("UI_ProcessLDAPRequest: can't import new cert into the db!n");
  2140.   
  2141.  loser:
  2142.   SSM_NotifyUIEvent(req->target);
  2143.   PR_FREEIF(key);
  2144.   return rv;
  2145. }
  2146. SSMStatus 
  2147. SSM_CompleteLDAPLookup(SSMControlConnection *ctrl, char * ldapserver, 
  2148.        char *emailaddr)
  2149. {
  2150.   SSMStatus rv = SSM_FAILURE;
  2151.   char * tmpStr, * servername, *baseDN, *mailAttribs;
  2152.   SECItem newCert = { siBuffer, NULL, 0};
  2153.   CERTCertificate * cert = NULL;
  2154.   SECStatus secrv; 
  2155.   int port = 0;
  2156.   char cert_attribs[] = "userSMIMECertificate,usercertificate;binary";
  2157.   cert_struct * certs[2] = {NULL, NULL}; /* one for ea cert_attrib */
  2158.   
  2159.   if (!ctrl || !ldapserver) 
  2160.     goto loser;
  2161.   PR_ASSERT(SSM_IsA((SSMResource *)ctrl, SSM_RESTYPE_CONTROL_CONNECTION));
  2162.   
  2163.   tmpStr = PR_smprintf("%s.serverName", ldapserver);
  2164.   rv = PREF_GetStringPref(ctrl->m_prefs,tmpStr,
  2165.   &servername);
  2166.   PR_FREEIF(tmpStr);
  2167.   if (rv != SSM_SUCCESS) {
  2168.     SSM_DEBUG("CompleteLDAPLookup: can't find LDAP server %s!n",ldapserver);
  2169.     goto loser;
  2170.   }
  2171.   
  2172.   /* DN, mail attribs and port are not supplied from UI, look up in prefs */
  2173.   tmpStr = PR_smprintf("%s.searchBase",ldapserver);
  2174.   rv = PREF_GetStringPref(ctrl->m_prefs, tmpStr, &baseDN);
  2175.   PR_FREEIF(tmpStr);
  2176.   if (rv != SSM_SUCCESS) {
  2177.     SSM_DEBUG("CompleteLDAPLookup: can't find baseDN for %s!n",ldapserver);
  2178.     goto loser;
  2179.   }
  2180.   tmpStr = PR_smprintf("%s.attributes.mail",ldapserver);
  2181.   rv = PREF_GetStringPref(ctrl->m_prefs, tmpStr, &mailAttribs);
  2182.   PR_FREEIF(tmpStr);
  2183.   if (rv != SSM_SUCCESS) {
  2184.     SSM_DEBUG("CompleteLDAPLookup:can't find mail attributes for %s!n",
  2185.       ldapserver);
  2186.     goto loser;
  2187.   }
  2188.   tmpStr = PR_smprintf("%s.port",ldapserver);
  2189.   rv = PREF_GetIntPref(ctrl->m_prefs, tmpStr, &port);
  2190.   PR_FREEIF(tmpStr);
  2191.   if (rv != SSM_SUCCESS)
  2192.     port = 0;
  2193. #ifndef XP_MAC
  2194.   rv = LDAPCertSearch(emailaddr, servername, baseDN, port, 1, NULL, NULL, 
  2195.       NULL, mailAttribs, cert_attribs, certs);
  2196. #else
  2197.   rv = SSM_FAILURE; /* don't yet support LDAP on the Mac */
  2198. #endif
  2199.   if (rv != SSM_SUCCESS) {
  2200.     SSM_DEBUG("CompleteLDAPLookup: ldap search did not find anything!n");
  2201.     goto loser;
  2202.   }
  2203.   /* Go thru the possible multiple Certs retrieved from LDAP */
  2204.   rv = SSM_FAILURE; /* default case - no good Certs found */
  2205.   /* first check any userSMIMECerts found */
  2206.   if (certs[0]) {
  2207.   PRBool ret;
  2208.   SEC_PKCS7ContentInfo *ci;
  2209.   SECItem digest;
  2210.   unsigned char nullsha1[SHA1_LENGTH];
  2211.       struct cert_struct_def * cert_ptr;
  2212.       cert_ptr = certs[0];
  2213.       while (cert_ptr->cert_len) {
  2214.           newCert.len = cert_ptr->cert_len;
  2215.           newCert.data = (unsigned char *) cert_ptr->cert;
  2216.   ci = SEC_PKCS7DecodeItem(&newCert, NULL, NULL,
  2217.      NULL, NULL, NULL, NULL, NULL);
  2218.   if ( ci != NULL ) {
  2219.   if ( SEC_PKCS7ContentIsSigned(ci) ) {
  2220.   rv = SHA1_HashBuf(nullsha1, nullsha1, 0);
  2221.   if ( rv != SECSuccess ) {
  2222.   break;
  2223.   }
  2224.   digest.len = SHA1_LENGTH;
  2225.   digest.data = nullsha1;
  2226.   ret = SEC_PKCS7VerifyDetachedSignature(ci,
  2227. certUsageEmailRecipient,
  2228. &digest,
  2229. HASH_AlgSHA1,
  2230. PR_TRUE);
  2231.   if (ret == PR_TRUE) {
  2232.   rv = SSM_SUCCESS;
  2233.   }
  2234.   }
  2235.   }
  2236.           PR_Free(cert_ptr->cert);
  2237.           *cert_ptr++;
  2238.       }
  2239.       PR_Free(certs[0]);
  2240.   }
  2241.   /* If no valid Certs found yet, try userCertificate;binary */
  2242.   if (rv == SSM_FAILURE && certs[1]) {
  2243.       struct cert_struct_def * cert_ptr;
  2244.       cert_ptr = certs[1];
  2245.       while (cert_ptr->cert_len) {
  2246.           newCert.len = cert_ptr->cert_len;
  2247.           newCert.data = (unsigned char *) cert_ptr->cert;
  2248. /*        memcpy(newCert.data, cert_ptr->cert, newCert.len); */
  2249.           /* Okay, got a Cert - so try to store in CertDB */
  2250.           cert = CERT_NewTempCertificate(ctrl->m_certdb, &newCert, NULL,
  2251.                                          PR_FALSE, PR_TRUE);
  2252.           if (cert != NULL) {
  2253.               secrv = CERT_SaveImportedCert(cert, certUsageEmailRecipient,
  2254.                                             PR_FALSE, NULL);
  2255.               if (secrv == SECSuccess) {
  2256.                   secrv = CERT_SaveSMimeProfile(cert, NULL, NULL);
  2257.                   rv = SSM_SUCCESS;
  2258.               }
  2259.           }
  2260.           /* and free LDAP cert memory for this cert */
  2261.           PR_Free(cert_ptr->cert);
  2262.           *cert_ptr++;
  2263.       }
  2264.       PR_Free(certs[1]);
  2265.   }
  2266. #if 0 
  2267.   /* Store the cert in the certdb */
  2268.   cert = CERT_NewTempCertificate(ctrl->m_certdb, &newCert,
  2269.  NULL, PR_FALSE, PR_TRUE);
  2270.   if ( cert != NULL ) {
  2271.     secrv = CERT_SaveImportedCert(cert, certUsageEmailRecipient,
  2272.   PR_FALSE, NULL);
  2273.     if ( secrv == SECSuccess ) 
  2274.       secrv = CERT_SaveSMimeProfile(cert, NULL, NULL);
  2275.   } else {
  2276.     SSM_DEBUG("CompleteLDAPLookup: couldn't import cert into DB!n");
  2277.     rv = SSM_FAILURE;
  2278.   }
  2279. #endif
  2280.  loser:
  2281.     return rv;
  2282. }
  2283. SSMStatus SSM_LDAPServerListKeywordHandler(SSMTextGenContext * cx)
  2284. {
  2285.   SSMStatus rv = SSM_FAILURE;
  2286.   char * tmpStr = NULL, * desc_key = NULL;
  2287.   char ** ldap_servers = NULL, ** ptr, * server = NULL;
  2288.   char * wrapper = NULL;
  2289.   cx->m_result = NULL;
  2290.   /* get all the ldap servers available and present them in a list */
  2291.   rv = PREF_CreateChildList(cx->m_request->ctrlconn->m_prefs, 
  2292.     "ldap_2.servers", &ldap_servers);
  2293.   if (rv != SSM_SUCCESS || !ldap_servers)
  2294.     goto done;
  2295.   
  2296.   rv = SSM_GetAndExpandTextKeyedByString(cx, "ldap_server_list_prefix", 
  2297.  &cx->m_result);
  2298.   if (rv != SSM_SUCCESS)
  2299.     goto done;
  2300.   rv = SSM_GetAndExpandTextKeyedByString(cx, "ldap_server_list_item", 
  2301.  &wrapper);
  2302.   if (rv != SSM_SUCCESS) 
  2303.     goto done;
  2304.   ptr = ldap_servers;
  2305.   while (*ptr) {
  2306.     desc_key = PR_smprintf("ldap_2.servers.%s.description", *ptr);
  2307.     rv = PREF_GetStringPref(cx->m_request->ctrlconn->m_prefs,
  2308.     desc_key, &server);
  2309.     PR_FREEIF(desc_key); desc_key = NULL;
  2310.     if (rv != SSM_SUCCESS)
  2311.       goto done;
  2312.     tmpStr = PR_smprintf(wrapper, *ptr, server);
  2313.     PR_Free(*ptr); 
  2314.     rv = SSM_ConcatenateUTF8String(&cx->m_result, tmpStr);
  2315.     PR_FREEIF(tmpStr); tmpStr = NULL;
  2316.     if (rv != SSM_SUCCESS) 
  2317.       goto done;
  2318.     ptr++;
  2319.   }
  2320.   PR_Free(ldap_servers); ldap_servers = NULL;
  2321.   SSM_GetAndExpandTextKeyedByString(cx, "ldap_server_list_suffix",
  2322.     &tmpStr);
  2323.   rv = SSM_ConcatenateUTF8String(&cx->m_result, tmpStr);
  2324.  done:
  2325.   PR_FREEIF(wrapper);
  2326.   PR_FREEIF(tmpStr);
  2327.   if (rv != SSM_SUCCESS)
  2328.     PR_FREEIF(cx->m_result);
  2329.   return rv;
  2330. }
  2331. char * SSM_GetCAPolicyString(char * org, unsigned long noticeNum, void * arg)
  2332. {
  2333.   SSMControlConnection * ctrl = (SSMControlConnection *)arg;
  2334.   char * alphaorg = NULL, * ptr, *aptr, * key = NULL, * value = NULL;
  2335.   int c;
  2336.   if (!ctrl || !org) 
  2337.     goto loser;
  2338.   PR_ASSERT(ctrl && SSM_IsAKindOf((SSMResource *)ctrl,SSM_RESTYPE_CONTROL_CONNECTION));
  2339.   alphaorg = (char *) PORT_ZAlloc(sizeof(org) + 1);
  2340.   if (!alphaorg) 
  2341.     goto loser;
  2342.   
  2343.   ptr = org; aptr = alphaorg;
  2344.   while ( (c=*ptr) != '') {
  2345.     if ( isalpha(c) ) {
  2346.       * aptr = c;
  2347.       aptr++;
  2348.     }
  2349.     ptr++;
  2350.   }
  2351.   *aptr = '';
  2352.   
  2353.   key = PR_smprintf("security.canotices.%s.notice%ld", alphaorg, noticeNum);
  2354.   if (!key)
  2355.     goto loser;
  2356.   PREF_GetStringPref(ctrl->m_prefs, key, &value);
  2357.   
  2358.  loser:
  2359.   PR_FREEIF(alphaorg);
  2360.   PR_FREEIF(key);
  2361.   return value?PL_strdup(value):NULL;
  2362. }
  2363. SSMStatus
  2364. SSM_FillTextWithEmails(SSMTextGenContext *cx)
  2365. {
  2366.   SSMStatus rv;
  2367.   char *emails;
  2368.   rv = SSM_HTTPParamValue(cx->m_request, "emailAddresses", &emails);
  2369.   PR_FREEIF(cx->m_result);
  2370.   if (rv == SSM_SUCCESS) {
  2371.     cx->m_result = PL_strdup(emails);
  2372.   } else {
  2373.     cx->m_result = PL_strdup("");
  2374.   }
  2375.   return SSM_SUCCESS;
  2376. }
  2377. SSMStatus
  2378. SSM_GetWindowOffset(SSMTextGenContext *cx)
  2379. {
  2380.   char *offset=NULL;
  2381.   SSMStatus rv;
  2382.   int offsetVal;
  2383.   
  2384.   rv = SSM_HTTPParamValue(cx->m_request, "windowOffset", &offset);
  2385.   if (rv != SSM_SUCCESS) {
  2386.     offsetVal = 0;
  2387.   } else {
  2388.     offsetVal = atoi (offset);
  2389.   }
  2390.   offsetVal += 20;
  2391.   PR_FREEIF(cx->m_result);
  2392.   cx->m_result = PR_smprintf("%d", offsetVal);
  2393.   return SSM_SUCCESS;
  2394. }
  2395. SSMStatus
  2396. SSM_MakeUniqueNameForIssuerWindow(SSMTextGenContext *cx)
  2397. {
  2398.   SSMResourceCert *certres;
  2399.   CERTCertificate *issuer, *serverCert;
  2400.   char *certHex=NULL, *issuerHex=NULL;
  2401.   SSMSSLDataConnection *sslConn;
  2402.   if (SSM_IsAKindOf(cx->m_request->target, SSM_RESTYPE_CERTIFICATE)) {
  2403.       certres = (SSMResourceCert*)cx->m_request->target;
  2404.       serverCert = certres->cert;
  2405.   } else if (SSM_IsAKindOf(cx->m_request->target, 
  2406.    SSM_RESTYPE_SSL_DATA_CONNECTION)) {
  2407.       sslConn = (SSMSSLDataConnection*)cx->m_request->target;
  2408.       serverCert = SSL_PeerCertificate(sslConn->socketSSL);
  2409.       if (serverCert == NULL) {
  2410. goto loser;
  2411.       }
  2412.   } else {
  2413.       goto loser;
  2414.   }
  2415.   issuer = CERT_FindCertIssuer(serverCert,PR_Now(),certUsageAnyCA);
  2416.   certHex = CERT_Hexify(&serverCert->serialNumber,0);
  2417.   if (issuer != NULL) {
  2418.     issuerHex = CERT_Hexify(&issuer->serialNumber,0);
  2419.     CERT_DestroyCertificate(issuer);
  2420.   }
  2421.   PR_FREEIF(cx->m_result);
  2422.   cx->m_result = PR_smprintf("%s%s", certHex, (issuerHex) ? issuerHex : "");
  2423.   PR_FREEIF(issuerHex);
  2424.   PR_Free(certHex);
  2425.   return SSM_SUCCESS;
  2426.  loser:
  2427.   return SSM_FAILURE;
  2428. }
  2429. SSMStatus 
  2430. SSM_ShowCertIssuer(HTTPRequest *req)
  2431. {
  2432.   SSMResourceCert *certres;
  2433.   SSMResource *issuerRes=NULL;
  2434.   CERTCertificate *issuer=NULL;
  2435.   char *tmpl = NULL, *finalText=NULL;
  2436.   SSMTextGenContext *cx=NULL;
  2437.   SSMStatus rv;
  2438.   SSMResourceID issuerResID;
  2439.   char *htmlString=NULL, *params = NULL, *offsetString;
  2440.   int offset;
  2441.   if (!SSM_IsAKindOf(req->target, SSM_RESTYPE_CERTIFICATE)) {
  2442.     goto loser;
  2443.   }
  2444.   certres = (SSMResourceCert*)req->target;
  2445.   issuer = CERT_FindCertIssuer(certres->cert, PR_Now(), certUsageAnyCA);
  2446.   if (issuer == NULL) {
  2447.     /*
  2448.      * Instead of bailing out entirely, pop up a dialog that let's the
  2449.      * user know the issuer was not found.
  2450.      */
  2451.     
  2452.     params = PR_smprintf("get?baseRef=issuer_not_found&target=%d",
  2453.  req->target->m_id);
  2454.   } else {
  2455.     
  2456.     rv = (SSMStatus) SSM_CreateResource(SSM_RESTYPE_CERTIFICATE, (void*)issuer,
  2457. req->ctrlconn, &issuerResID, &issuerRes);
  2458.     if (rv != SSM_SUCCESS) {
  2459.       goto loser;
  2460.     }
  2461.     rv = SSM_HTTPParamValue(req, "windowOffset", &offsetString);
  2462.     if (rv != SSM_SUCCESS) {
  2463.       offset = 0;
  2464.     } else {
  2465.       offset = atoi (offsetString);
  2466.     }
  2467.     
  2468.     /*  Now let's build up the URL*/
  2469.     htmlString = SSM_ConvertStringToHTMLString(issuer->nickname);
  2470.     params = PR_smprintf("get?baseRef=cert_view&target=%1$d&windowOffset=%2$d", 
  2471.  issuerResID, offset);
  2472.     PR_Free(htmlString);
  2473.     htmlString = NULL;
  2474.   } 
  2475.   rv =SSMTextGen_NewTopLevelContext(req, &cx);
  2476.   if (rv != SSM_SUCCESS) {
  2477.     goto loser;
  2478.   }
  2479.   rv = SSM_GetAndExpandText(cx, "refresh_window_content", &tmpl);
  2480.   if (rv != SSM_SUCCESS) {
  2481.     goto loser;
  2482.   }
  2483.   finalText = PR_smprintf(tmpl, params);
  2484.   SSM_HTTPSendOKHeader(req, NULL, "text/html");
  2485.   SSM_HTTPSendUTF8String(req, finalText);
  2486.   PR_FREEIF(tmpl);
  2487.   PR_Free(finalText);
  2488.   SSMTextGen_DestroyContext(cx);
  2489.   req->sentResponse = PR_TRUE;
  2490.   return SSM_SUCCESS;
  2491.  loser:
  2492.   PR_FREEIF(tmpl);
  2493.   PR_FREEIF(finalText);
  2494.   if (cx != NULL) {
  2495.     SSMTextGen_DestroyContext(cx);
  2496.   }
  2497.   return SSM_FAILURE;
  2498. }
  2499. SSMStatus SSM_PrettyPrintCert(HTTPRequest *req)
  2500. {
  2501.     SSMResource *res;
  2502.     SSMResourceCert *certres;
  2503.     SSMStatus rv;
  2504.     char *prefix=NULL, *suffix=NULL, *certName;
  2505.     SSMTextGenContext *cx=NULL;
  2506.     res = req->target;
  2507.     if (!SSM_IsAKindOf(res, SSM_RESTYPE_CERTIFICATE)) {
  2508.         return SSM_FAILURE;
  2509.     }
  2510.     certres = (SSMResourceCert*)res;
  2511.     rv = SSMTextGen_NewTopLevelContext(req, &cx);
  2512.     if (rv != SSM_SUCCESS) {
  2513.         goto loser;
  2514.     }
  2515.     rv = SSM_GetAndExpandText(cx, "certPrettyPrefix", &prefix);
  2516.     if (rv != SSM_SUCCESS) {
  2517.       goto loser;
  2518.     }
  2519.     rv = SSM_GetAndExpandText(cx, "certPrettySuffix", &suffix);
  2520.     if (rv != SSM_SUCCESS) {
  2521.       goto loser;
  2522.     }
  2523.     rv = SSM_HTTPSendOKHeader(req, NULL, "text/html");
  2524.     if (rv != SSM_SUCCESS) {
  2525.       goto loser;
  2526.     }
  2527.     rv = SSM_HTTPSendUTF8String(req, prefix);
  2528.     if (rv != SSM_SUCCESS) {
  2529.       goto loser;
  2530.     }
  2531.     certName = (certres->cert->nickname) ? certres->cert->nickname :
  2532.                                            certres->cert->emailAddr;
  2533.     SSM_HTTPSendUTF8String(req, certName);
  2534.     SSM_HTTPSendUTF8String(req, "nn");
  2535.     SSM_PrettyPrintDER(req->sock, &certres->cert->derCert, 0);
  2536.     SSM_HTTPSendUTF8String(req, suffix);
  2537.     req->sentResponse = PR_TRUE;
  2538.     return SSM_SUCCESS;
  2539.  loser:
  2540.     if (cx != NULL) {
  2541.       SSMTextGen_DestroyContext(cx);
  2542.     }
  2543.     PR_FREEIF(prefix);
  2544.     PR_FREEIF(suffix);
  2545.     return SSM_FAILURE; 
  2546. }