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

CA认证

开发平台:

WINDOWS

  1. /* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
  2. /* 
  3.  * The contents of this file are subject to the Mozilla Public
  4.  * License Version 1.1 (the "License"); you may not use this file
  5.  * except in compliance with the License. You may obtain a copy of
  6.  * the License at http://www.mozilla.org/MPL/
  7.  * 
  8.  * Software distributed under the License is distributed on an "AS
  9.  * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
  10.  * implied. See the License for the specific language governing
  11.  * rights and limitations under the License.
  12.  * 
  13.  * The Original Code is the Netscape security libraries.
  14.  * 
  15.  * The Initial Developer of the Original Code is Netscape
  16.  * Communications Corporation.  Portions created by Netscape are 
  17.  * Copyright (C) 1994-2000 Netscape Communications Corporation.  All
  18.  * Rights Reserved.
  19.  * 
  20.  * Contributor(s):
  21.  * 
  22.  * Alternatively, the contents of this file may be used under the
  23.  * terms of the GNU General Public License Version 2 or later (the
  24.  * "GPL"), in which case the provisions of the GPL are applicable 
  25.  * instead of those above.  If you wish to allow use of your 
  26.  * version of this file only under the terms of the GPL and not to
  27.  * allow others to use your version of this file under the MPL,
  28.  * indicate your decision by deleting the provisions above and
  29.  * replace them with the notice and other provisions required by
  30.  * the GPL.  If you do not delete the provisions above, a recipient
  31.  * may use your version of this file under either the MPL or the
  32.  * GPL.
  33.  */
  34. #include "cmtcmn.h"
  35. #if defined(XP_UNIX) || defined(XP_BEOS) || defined(XP_OS2)
  36. #include <sys/types.h>
  37. #include <sys/socket.h>
  38. #include <netinet/in.h>
  39. #else
  40. #ifdef XP_MAC
  41. #include "macsocket.h"
  42. #include "cmtmac.h"
  43. #else
  44. #include <windows.h>
  45. #include <winsock.h>
  46. #endif
  47. #endif
  48. #include <errno.h>
  49. #include "cmtutils.h"
  50. #include "messages.h"
  51. #include <string.h>
  52. #include "cmtjs.h"
  53. CMUint32 CMT_DecodeAndCreateTempCert(PCMT_CONTROL control, char * data, 
  54.       CMUint32 len, int type) 
  55. {
  56.   CMTItem message;
  57.   DecodeAndCreateTempCertRequest request;
  58.   SingleNumMessage reply;
  59.   /* Set up the request */
  60.   request.type = type;
  61.   request.cert.len = len;
  62.   request.cert.data = (unsigned char *) data;
  63.   /* Encode the request */
  64.   if (CMT_EncodeMessage(DecodeAndCreateTempCertRequestTemplate, &message, &request) != CMTSuccess) {
  65.       goto loser;
  66.   }
  67.   /* Set the message request type */
  68.   message.type = SSM_REQUEST_MESSAGE | SSM_CERT_ACTION | SSM_DECODE_TEMP_CERT;
  69.   /* Send the message and get the response */
  70.   if (CMT_SendMessage(control, &message) == CMTFailure) {
  71.     goto loser;
  72.   }
  73.   /* Validate the message reply type */
  74.   if (message.type != (SSM_REPLY_OK_MESSAGE | SSM_CERT_ACTION | SSM_DECODE_TEMP_CERT)) {
  75.     goto loser;
  76.   }
  77.   /* Decode the reply */
  78.   if (CMT_DecodeMessage(SingleNumMessageTemplate, &reply, &message) != CMTSuccess) {
  79.       goto loser;
  80.   }
  81.   /* Return the cert id */
  82.   return reply.value;
  83. loser:
  84.   return 0;
  85. }
  86. void CMT_DestroyCertificate(PCMT_CONTROL control, CMUint32 certID)
  87. {
  88.   CMTItem message;
  89.   SingleNumMessage request;
  90.   /* Set up the request */
  91.   request.value = certID;
  92.   /* Encode the request */
  93.   if (CMT_EncodeMessage(SingleNumMessageTemplate, &message, &request) != CMTSuccess) {
  94.       goto loser;
  95.   }
  96.   /* Set the message request type */
  97.   message.type = SSM_REQUEST_MESSAGE | SSM_CERT_ACTION | SSM_DESTROY_CERT;
  98.   /* Send the message and get the response */
  99.   if (CMT_SendMessage(control, &message) == CMTFailure) {
  100.     goto loser;
  101.   }
  102.   /* Validate the message reply type */
  103.   if (message.type != (SSM_REPLY_OK_MESSAGE | SSM_CERT_ACTION | SSM_DESTROY_CERT)) {
  104.     goto loser;
  105.   }
  106. loser:
  107.   /* do something on fail ? */
  108.   return;
  109. }
  110. char * cmt_processreplytooldkeygen(CMTItem *message,
  111.                                    CMKeyGenTagArg * arg,
  112.                                    CMKeyGenTagReq *next)
  113. {
  114.   char * keystring = NULL;
  115.   SingleStringMessage keyreply;
  116.   GenKeyOldStyleTokenRequest tokenrequest;
  117.   NameList * tokens = NULL;
  118.   GenKeyOldStylePasswordRequest pwdrequest;
  119.   CMKeyGenPassword * pwdstruct = NULL;
  120.   int i;
  121.   /* check what kind of response we got */
  122.   switch (message->type) {
  123.   case (SSM_REPLY_OK_MESSAGE | SSM_KEYGEN_TAG | SSM_KEYGEN_DONE):
  124.       /* Decode the reply */
  125.       if (CMT_DecodeMessage(SingleStringMessageTemplate, &keyreply, message) 
  126.           != CMTSuccess) 
  127.           goto loser;
  128.       keystring = strdup(keyreply.string);
  129.       *next = CM_KEYGEN_DONE;
  130.       break;
  131.   case (SSM_REPLY_OK_MESSAGE | SSM_KEYGEN_TAG | SSM_KEYGEN_TOKEN):
  132.       /* Decode the reply */
  133.       if (CMT_DecodeMessage(GenKeyOldStyleTokenRequestTemplate, &tokenrequest,
  134.                             message) != CMTSuccess) 
  135.           goto loser;
  136.       tokens = (NameList *) malloc(sizeof(NameList));
  137.       tokens->numitems = tokenrequest.numtokens;
  138.       tokens->names = (char **) calloc(tokenrequest.numtokens, sizeof(char *));
  139.       for (i = 0; i<tokenrequest.numtokens; i++)
  140.           tokens->names[i] = strdup(tokenrequest.tokenNames[i]);
  141.       arg->rid = tokenrequest.rid;
  142.       arg->current = tokens;
  143.       *next = CM_KEYGEN_PICK_TOKEN ;
  144.       break;
  145.   case (SSM_REPLY_OK_MESSAGE | SSM_KEYGEN_TAG | SSM_KEYGEN_PASSWORD):
  146.        if (CMT_DecodeMessage(GenKeyOldStylePasswordRequestTemplate, 
  147.                              &pwdrequest,message) != CMTSuccess) 
  148.            goto loser;
  149.        arg->rid = pwdrequest.rid;
  150.        pwdstruct = (CMKeyGenPassword *) malloc(sizeof(CMKeyGenPassword));
  151.        pwdstruct->password = NULL;
  152.        pwdstruct->minpwd = pwdrequest.minpwdlen;
  153.        pwdstruct->maxpwd = pwdrequest.maxpwdlen;
  154.        pwdstruct->internalToken = pwdrequest.internal;
  155.        arg->current = pwdstruct;
  156.        *next = CM_KEYGEN_SET_PASSWORD;
  157.        break;
  158.   default:
  159.       /* error or bad message type */
  160.       *next = CM_KEYGEN_ERR;
  161.       break;
  162.   }
  163.   return keystring;
  164.  loser:
  165.   if (keystring)
  166.       free (keystring);
  167.   return NULL;
  168. }
  169. char * CMT_GetGenKeyResponse(PCMT_CONTROL control, CMKeyGenTagArg * arg, 
  170.                              CMKeyGenTagReq *next)
  171. {
  172.     CMTItem message;
  173.     char *keystring = NULL;
  174.     CMTSocket sock;
  175.     memset(&message, 0, sizeof(CMTItem));
  176.     CMT_LOCK(control->mutex);
  177.     sock = control->sock;
  178.     if (control->sockFuncs.select(&sock, 1, 1) == sock) {
  179.         /* Make sure there's a message waiting to be read so 
  180.          * that we avoid deadlock
  181.          */
  182.         CMT_ReadMessageDispatchEvents(control, &message);
  183.         keystring = cmt_processreplytooldkeygen(&message, arg, next);
  184.     }
  185.     CMT_UNLOCK(control->mutex);
  186.     return keystring;
  187. }
  188. char * CMT_GenKeyOldStyle(PCMT_CONTROL control, CMKeyGenTagArg * arg, 
  189.                           CMKeyGenTagReq *next)
  190. {
  191.   char * keystring = NULL;
  192.   CMTItem message;
  193.   GenKeyOldStyleRequest request;
  194.   GenKeyOldStyleTokenReply tokenreply;
  195.   GenKeyOldStylePasswordReply passwordreply;
  196.   
  197.   if (!arg || !next) 
  198.       goto loser;
  199.   
  200.   /* Set up appropriate request */
  201.   switch (arg->op) {
  202.   case CM_KEYGEN_START: 
  203.       {
  204.           CMKeyGenParams * params = (CMKeyGenParams *) arg->current;
  205.           request.choiceString = params->choiceString;
  206.           request.challenge = params->challenge;
  207.           request.typeString = params->typeString;
  208.           request.pqgString = params->pqgString;
  209.           if (CMT_EncodeMessage(GenKeyOldStyleRequestTemplate, &message, 
  210.                                 &request) != CMTSuccess) 
  211.               goto loser;
  212.           message.type = (SSM_REQUEST_MESSAGE | SSM_KEYGEN_TAG | 
  213.                           SSM_KEYGEN_START);
  214.        
  215.       }
  216.   break;
  217.   case CM_KEYGEN_PICK_TOKEN:
  218.       tokenreply.rid = arg->rid;
  219.       tokenreply.cancel = (CMBool) arg->cancel;
  220.       if (!arg->cancel)
  221.           tokenreply.tokenName = arg->tokenName;
  222.       /* Encode the request */
  223.       if (CMT_EncodeMessage(GenKeyOldStyleTokenReplyTemplate, &message, 
  224.                             &tokenreply) != CMTSuccess) 
  225.           goto loser;  
  226.       message.type = (SSM_REQUEST_MESSAGE | SSM_KEYGEN_TAG |SSM_KEYGEN_TOKEN);
  227.       break;
  228.   case CM_KEYGEN_SET_PASSWORD:
  229.       passwordreply.rid = arg->rid;
  230.       passwordreply.cancel = (CMBool) arg->cancel;
  231.       if (!arg->cancel)
  232.           passwordreply.password = ((CMKeyGenPassword*)arg->current)->password;
  233.       /* Encode the request */
  234.     if (CMT_EncodeMessage(GenKeyOldStylePasswordReplyTemplate, &message, 
  235.                           &passwordreply) != CMTSuccess) 
  236.         goto loser;  
  237.     /* Set the message request type */
  238.     message.type = SSM_REQUEST_MESSAGE |SSM_KEYGEN_TAG |SSM_KEYGEN_PASSWORD;
  239.     break;
  240.   default:
  241.       /* don't know what to do - bad argument? */
  242.       goto loser;
  243.   }
  244.       
  245.   /* Send the message */
  246.   if (CMT_SendMessage(control, &message) == CMTFailure) {
  247.     goto loser;
  248.   }
  249.   if (arg->current)
  250.       free(arg->current);
  251.   arg->current = NULL;
  252.   
  253.   keystring = cmt_processreplytooldkeygen(&message, arg, next);
  254. loser:
  255.   return keystring;
  256. }
  257. char ** CMT_GetKeyChoiceList(PCMT_CONTROL control, char * type, char * pqgString)
  258. {
  259.   CMTItem message;
  260.   int i;
  261.   char **result = NULL;
  262.   GetKeyChoiceListRequest request;
  263.   GetKeyChoiceListReply reply;
  264.   /* Set up the request */
  265.   request.type = type;
  266.   request.pqgString = pqgString;
  267.   /* Encode the message */
  268.   if (CMT_EncodeMessage(GetKeyChoiceListRequestTemplate, &message, &request) != CMTSuccess) {
  269.       goto loser;
  270.   }
  271.   
  272.   /* Set the message request type */
  273.   message.type = SSM_REQUEST_MESSAGE | SSM_KEYGEN_TAG | SSM_GET_KEY_CHOICE;
  274.   /* Send the message */
  275.   if (CMT_SendMessage(control, &message) == CMTFailure) {
  276.      goto loser;
  277.   }
  278.   /* Validate the message response type */
  279.   if (message.type != (SSM_REPLY_OK_MESSAGE | SSM_KEYGEN_TAG | SSM_GET_KEY_CHOICE)) {
  280.       goto loser;
  281.   }
  282.   /* Decode the reply */
  283.   if (CMT_DecodeMessage(GetKeyChoiceListReplyTemplate, &reply, &message) != CMTSuccess) {
  284.       goto loser;
  285.   }
  286.   result = (char **) calloc(reply.nchoices+1, sizeof(char *));
  287.   if (!result) {
  288.       goto loser;
  289.   }
  290.   for (i = 0; i<reply.nchoices; i++) {
  291.       result[i] = reply.choices[i];
  292.   }
  293.   result[i] = 0;
  294. loser:
  295.   return result;
  296. }
  297.  
  298. CMTStatus CMT_ImportCertificate(PCMT_CONTROL control, CMTItem * cert, CMUint32 * certResourceID)
  299. {
  300.     CMTItem message;
  301.     SingleItemMessage request;
  302.     ImportCertReply reply;
  303.     /* Do some parameter checking */
  304.     if (!control || !cert || !certResourceID) {
  305.         goto loser;
  306.     }
  307.     /* Set up the request */
  308.     request.item = *cert;
  309.     /* Encode the request */
  310.     if (CMT_EncodeMessage(SingleItemMessageTemplate, &message, &request) != CMTSuccess) {
  311.         goto loser;
  312.     }
  313.     /* Set the message request type */
  314.     message.type = SSM_REQUEST_MESSAGE | SSM_CERT_ACTION | SSM_IMPORT_CERT;
  315.     /* Send the message and get the response */
  316.     if (CMT_SendMessage(control, &message) == CMTFailure) {
  317.         goto loser;
  318.     }
  319.     /* Validate the reply */
  320.     if (message.type != (SSM_REPLY_OK_MESSAGE | SSM_CERT_ACTION | SSM_IMPORT_CERT)) {
  321.         goto loser;
  322.     }
  323.     /* Decode the reply */
  324.     if (CMT_DecodeMessage(ImportCertReplyTemplate, &reply, &message) != CMTSuccess) {
  325.         goto loser;
  326.     }
  327.     /* Success */
  328.     if (reply.result == 0) {
  329.         *certResourceID = reply.resID;
  330.         return CMTSuccess;
  331.     }
  332. loser:
  333.     *certResourceID = 0;
  334.     return CMTFailure;
  335. }
  336. CMUint32 CMT_DecodeCertFromPackage(PCMT_CONTROL  control, 
  337.  char * certbuf, int certlen)
  338. {
  339.     CMTItem message;
  340.     SingleItemMessage request;
  341.     SingleNumMessage reply;
  342.     /* check parameters */
  343.     if (!control || !certbuf || certlen == 0) {
  344.         goto loser;
  345.     }
  346.     /* Set up the request */
  347.     request.item.data = (unsigned char *) certbuf;
  348.     request.item.len = certlen;
  349.     /* Encode the request */
  350.     if (CMT_EncodeMessage(SingleItemMessageTemplate, &message, &request) != CMTSuccess) {
  351.         goto loser;
  352.     }
  353.     /* Set the message request type */
  354.     message.type = SSM_REQUEST_MESSAGE | SSM_CERT_ACTION | SSM_DECODE_CERT;
  355.     /* Send the message and get the response */
  356.     if (CMT_SendMessage(control, &message) == CMTFailure) {
  357.         goto loser;
  358.     }
  359.     /* Validate the message reply type */
  360.     if (message.type != (SSM_REPLY_OK_MESSAGE | SSM_CERT_ACTION | SSM_DECODE_CERT)) {
  361.         goto loser;
  362.     }
  363.     /* Decode the reply */
  364.     if (CMT_DecodeMessage(SingleNumMessageTemplate, &reply, &message) != CMTSuccess) {
  365.         goto loser;
  366.     }
  367.     /* Return cert id */
  368.     return reply.value;
  369. loser:
  370.     return 0;
  371. }
  372. CMTStatus CMT_VerifyCertificate(PCMT_CONTROL control, CMUint32 certResourceID, CMUint32 certUsage, CMInt32 * result)
  373. {
  374.     CMTItem message;
  375.     VerifyCertRequest request;
  376.     SingleNumMessage reply;
  377.     /* Do some parameter checking */
  378.     if (!control || !result) {
  379.         goto loser;
  380.     }
  381.     /* Set the request */
  382.     request.resID = certResourceID;
  383.     request.certUsage = certUsage;
  384.     /* Encode the request */
  385.     if (CMT_EncodeMessage(VerifyCertRequestTemplate, &message, &request) != CMTSuccess) {
  386.         goto loser;
  387.     }
  388.     /* Set the message request type */
  389.     message.type = SSM_REQUEST_MESSAGE | SSM_CERT_ACTION | SSM_VERIFY_CERT;
  390.     /* Send the message and get the response */
  391.     if (CMT_SendMessage(control, &message) == CMTFailure) {
  392.         goto loser;
  393.     }
  394.     /* Validate the message reply type */
  395.     if (message.type != (SSM_REPLY_OK_MESSAGE | SSM_CERT_ACTION | SSM_VERIFY_CERT)) {
  396.         goto loser;
  397.     }
  398.     
  399.     /* Decode the reply */
  400.     if (CMT_DecodeMessage(SingleNumMessageTemplate, &reply, &message) != CMTSuccess) {
  401.         goto loser;
  402.     }
  403.     *result = reply.value;
  404.     if (*result == 0) {
  405.         return CMTSuccess;
  406.     }
  407. loser:
  408.     return CMTFailure;
  409. }
  410. CMTStatus CMT_FindCertificateByNickname(PCMT_CONTROL control, char * nickname, CMUint32 *resID)
  411. {
  412.     CMTItem message;
  413.     SingleStringMessage request;
  414.     SingleNumMessage reply;
  415.     /* Do some basic parameter checking */
  416.     if (!control || !nickname) {
  417.         goto loser;
  418.     }
  419.     /* Set the request */
  420.     request.string = nickname;
  421.     /* Encode the request */
  422.     if (CMT_EncodeMessage(SingleStringMessageTemplate, &message, &request) != CMTSuccess) {
  423.         goto loser;
  424.     }
  425.     /* Set the message request type */
  426.     message.type = SSM_REQUEST_MESSAGE | SSM_CERT_ACTION | SSM_FIND_BY_NICKNAME;
  427.     /* Send the message and get the response */
  428.     if (CMT_SendMessage(control, &message) == CMTFailure) {
  429.         goto loser;
  430.     }
  431.     /* Validate the message reply type */
  432.     if (message.type != (SSM_REPLY_OK_MESSAGE | SSM_CERT_ACTION | SSM_FIND_BY_NICKNAME)) {
  433.         goto loser;
  434.     }
  435.     /* Decode the reply */
  436.     if (CMT_DecodeMessage(SingleNumMessageTemplate, &reply, &message) != CMTSuccess) {
  437.         goto loser;
  438.     }
  439.     *resID = reply.value;
  440.     return CMTSuccess;
  441. loser:
  442.     *resID = 0;
  443.     return CMTFailure;
  444. }
  445. CMTStatus CMT_FindCertificateByKey(PCMT_CONTROL control, CMTItem *key, CMUint32 *resID)
  446. {
  447.     CMTItem message;
  448.     SingleItemMessage request;
  449.     SingleNumMessage reply;
  450.     /* Do some basic parameter checking */
  451.     if (!control || !key || !resID) {
  452.         goto loser;
  453.     }
  454.     /* Set up the request */
  455.     request.item = *key;
  456.     /* Encode the request */
  457.     if (CMT_EncodeMessage(SingleItemMessageTemplate, &message, &request) != CMTSuccess) {
  458.         goto loser;
  459.     }
  460.     /* Set the message request type */
  461.     message.type = SSM_REQUEST_MESSAGE | SSM_CERT_ACTION | SSM_FIND_BY_KEY;
  462.     /* Send the message and get the response */
  463.     if (CMT_SendMessage(control, &message) == CMTFailure) {
  464.         goto loser;
  465.     }
  466.     /* Validate the message reply type */
  467.     if (message.type != (SSM_REPLY_OK_MESSAGE | SSM_CERT_ACTION | SSM_FIND_BY_KEY)) {
  468.         goto loser;
  469.     }
  470.     /* Decode the reply */
  471.     if (CMT_DecodeMessage(SingleNumMessageTemplate, &reply, &message) != CMTSuccess) {
  472.         goto loser;
  473.     }
  474.     *resID = reply.value;
  475.     return CMTSuccess;
  476. loser:
  477.     *resID = 0;
  478.     return CMTFailure;
  479. }
  480. CMTStatus CMT_FindCertificateByEmailAddr(PCMT_CONTROL control, char * emailAddr, CMUint32 *resID)
  481. {
  482.     CMTItem message;
  483.     SingleStringMessage request;
  484.     SingleNumMessage reply;
  485.     /* Do some basic parameter checking */
  486.     if (!control || !emailAddr) {
  487.         goto loser;
  488.     }
  489.     /* Set up the request */
  490.     request.string = emailAddr;
  491.     /* Encode the message */
  492.     if (CMT_EncodeMessage(SingleStringMessageTemplate, &message, &request) != CMTSuccess) {
  493.         goto loser;
  494.     }
  495.     /* Set the message request type */
  496.     message.type = SSM_REQUEST_MESSAGE | SSM_CERT_ACTION | SSM_FIND_BY_EMAILADDR;
  497.     /* Send the message and get the response */
  498.     if (CMT_SendMessage(control, &message) == CMTFailure) {
  499.         goto loser;
  500.     }
  501.     /* Validate the message reply type */
  502.     if (message.type != (SSM_REPLY_OK_MESSAGE | SSM_CERT_ACTION | SSM_FIND_BY_EMAILADDR)) {
  503.         goto loser;
  504.     }
  505.     /* Decode the reply */
  506.     if (CMT_DecodeMessage(SingleNumMessageTemplate, &reply, &message) != CMTSuccess) {
  507.         goto loser;
  508.     }
  509.     *resID = reply.value;
  510.     return CMTSuccess;
  511. loser:
  512.     *resID = 0;
  513.     return CMTFailure;
  514. }
  515. CMTStatus CMT_AddCertificateToDB(PCMT_CONTROL control, CMUint32 resID, char *nickname, CMInt32 ssl, CMInt32 email, CMInt32 objectSigning)
  516. {
  517.     CMTItem message;
  518.     AddTempCertToDBRequest request;
  519.     /* Do some basic parameter checking */
  520.     if (!control || !nickname) {
  521.         goto loser;
  522.     }
  523.     /* Set up the request */
  524.     request.resID = resID;
  525.     request.nickname = nickname;
  526.     request.sslFlags = ssl;
  527.     request.emailFlags = email;
  528.     request.objSignFlags = objectSigning;
  529.     /* Encode the request */
  530.     if (CMT_EncodeMessage(AddTempCertToDBRequestTemplate, &message, &request) != CMTSuccess) {
  531.         goto loser;
  532.     }
  533.     /* Set the message request type */
  534.     message.type = SSM_REQUEST_MESSAGE | SSM_CERT_ACTION | SSM_ADD_TO_DB;
  535.     /* Send the message and get the response */
  536.     if (CMT_SendMessage(control, &message) == CMTFailure) {
  537.         goto loser;
  538.     }
  539.     /* Validate the message reply type */
  540.     if (message.type != (SSM_REPLY_OK_MESSAGE | SSM_CERT_ACTION | SSM_ADD_TO_DB)) {
  541.         goto loser;
  542.     }
  543.     return CMTSuccess;
  544. loser:
  545.     return CMTFailure;
  546. }
  547. CMT_CERT_LIST *CMT_MatchUserCert(PCMT_CONTROL control, CMInt32 certUsage, CMInt32 numCANames, char **caNames)
  548. {
  549.     CMTItem message;
  550.     CMT_CERT_LIST *certList;
  551.     int i;
  552.     MatchUserCertRequest request;
  553.     MatchUserCertReply reply;
  554.     /* Set up the request */
  555.     request.certType = certUsage;
  556.     request.numCANames = numCANames;
  557.     request.caNames = caNames;
  558.     /* Encode the request */
  559.     if (CMT_EncodeMessage(MatchUserCertRequestTemplate, &message, &request) != CMTSuccess) {
  560.         goto loser;
  561.     }
  562.     /* Set the message request type */
  563.     message.type = SSM_REQUEST_MESSAGE | SSM_CERT_ACTION | SSM_MATCH_USER_CERT;
  564.     /* Send the message and get the response */
  565.     if (CMT_SendMessage(control, &message) == CMTFailure) {
  566.         goto loser;
  567.     }
  568.     /* Validate the message reply type */
  569.     if (message.type != (SSM_REPLY_OK_MESSAGE | SSM_CERT_ACTION | SSM_MATCH_USER_CERT)) {
  570.         goto loser;
  571.     }
  572.     /* Decode the reply */
  573.     if (CMT_DecodeMessage(MatchUserCertReplyTemplate, &reply, &message) != CMTSuccess) {
  574.         goto loser;
  575.     }
  576.     /* Return a list of cert ids to the client */
  577.     certList = (CMT_CERT_LIST*)malloc(sizeof(CMT_CERT_LIST));
  578.     if (!certList) {
  579.         goto loser;
  580.     }
  581.     CMT_INIT_CLIST(&certList->certs);
  582.     certList->count = reply.numCerts;
  583.     for (i=0; i<reply.numCerts; i++) {
  584.         CMT_CERT_LIST_ELEMENT *cert;
  585.         cert = (CMT_CERT_LIST_ELEMENT*)malloc(sizeof(CMT_CERT_LIST_ELEMENT));
  586.         if (!cert) {
  587.             goto loser;
  588.         }
  589.         CMT_INIT_CLIST(&cert->links);
  590.         cert->certResID = reply.certs[i];
  591.         CMT_APPEND_LINK(&cert->links, &certList->certs);
  592.     }
  593.     /* Clean up */
  594.     return certList;
  595. loser:
  596.     CMT_DestroyCertList(certList);
  597.     return NULL;
  598. }
  599. void CMT_DestroyCertList(CMT_CERT_LIST *certList)
  600. {
  601.     /* XXX */
  602.     return;
  603. }
  604. CMTStatus CMT_CompareForRedirect(PCMT_CONTROL control, CMTItem *status1, 
  605.                                  CMTItem *status2, CMUint32 *res)
  606. {
  607.     RedirectCompareRequest request;
  608.     CMTItem message = { 0, NULL, 0 };
  609.     SingleNumMessage reply;
  610.     if (status1 == NULL || status2 == NULL || res == NULL) {
  611.         return CMTFailure;
  612.     }
  613.     request.socketStatus1Data.len  = status1->len;
  614.     request.socketStatus1Data.data = status1->data;
  615.     request.socketStatus2Data.len  = status2->len;
  616.     request.socketStatus2Data.data = status2->data;
  617.     
  618.     if (CMT_EncodeMessage(RedirectCompareRequestTemplate, &message, &request)
  619.         != CMTSuccess) {
  620.         goto loser;
  621.     }
  622.     message.type = SSM_REQUEST_MESSAGE | SSM_CERT_ACTION | 
  623.                    SSM_REDIRECT_COMPARE;
  624.     if (CMT_SendMessage(control, &message) != CMTSuccess) {
  625.         goto loser;
  626.     }
  627.     if (CMT_DecodeMessage(SingleNumMessageTemplate, &reply, &message)
  628.         != CMTSuccess) {
  629.         goto loser;
  630.     }
  631.     *res = reply.value;
  632.     free (message.data);
  633.     return CMTSuccess;
  634.  loser:
  635.     *res = 0;
  636.     if (message.data != NULL) {
  637.         free (message.data);
  638.     }
  639.     return CMTFailure;
  640. }
  641. CMTStatus
  642. CMT_DecodeAndAddCRL(PCMT_CONTROL control, unsigned char *derCrl,
  643.     CMUint32 len, char *url, int type, 
  644.                     char **errMess)
  645. {
  646.     DecodeAndAddCRLRequest request;
  647.     SingleNumMessage reply;
  648.     CMTItem message = { 0, NULL, 0 };
  649.     if (*errMess) *errMess = NULL;
  650.     request.derCrl.data = derCrl;
  651.     request.derCrl.len  = len;
  652.     request.type        = type;
  653.     request.url         = url;
  654.     if (CMT_EncodeMessage(DecodeAndAddCRLRequestTemplate, &message, &request)
  655. != CMTSuccess) {
  656.         goto loser;
  657.     }
  658.     message.type = SSM_REQUEST_MESSAGE | SSM_CERT_ACTION |
  659.                    SSM_DECODE_CRL;
  660.     if (CMT_SendMessage(control, &message) != CMTSuccess) {
  661.         goto loser;
  662.     }
  663.     
  664.     if (CMT_DecodeMessage(SingleNumMessageTemplate, &reply, &message) 
  665. != CMTSuccess) {
  666.         goto loser;
  667.     }
  668.     if (reply.value == 0) {
  669.         return CMTSuccess;
  670.     }
  671.     if (*errMess) {
  672.         if (CMT_GetLocalizedString(control, (SSMLocalizedString) reply.value, errMess) 
  673.     != CMTSuccess) {
  674.     *errMess = NULL;
  675.     }
  676.  loser:
  677.     return CMTFailure;
  678. }
  679. /* These functions are used by requests related with javascript
  680.  * "SecurityConfig".
  681.  */
  682. /* adds base64 encoded cert to the temp db and gets a lookup key */
  683. CMTItem* CMT_SCAddCertToTempDB(PCMT_CONTROL control, char* certStr,
  684.                                CMUint32 certLen)
  685. {
  686.     SingleItemMessage request;
  687.     SingleItemMessage reply;
  688.     CMTItem message;
  689.     CMTItem* certKey = NULL;
  690.     if ((certStr == NULL) || (certLen == 0)) {
  691.         goto loser;
  692.     }
  693.     /* pack the request */
  694.     request.item.len = certLen;
  695.     request.item.data = (unsigned char *) certStr;
  696.     /* encode the request */
  697.     if (CMT_EncodeMessage(SingleItemMessageTemplate, &message, &request) !=
  698.         CMTSuccess) {
  699.         goto loser;
  700.     }
  701.     /* set the message type */
  702.     message.type = SSM_REQUEST_MESSAGE | SSM_SEC_CFG_ACTION |
  703.         SSM_ADD_CERT_TO_TEMP_DB;
  704.     /* send the message and get the response */
  705.     if (CMT_SendMessage(control, &message) == CMTFailure) {
  706.         goto loser;
  707.     }
  708.     /* decode the reply */
  709.     if (message.type != (SSM_REPLY_OK_MESSAGE | SSM_SEC_CFG_ACTION |
  710.         SSM_ADD_CERT_TO_TEMP_DB)) {
  711.         goto loser;
  712.     }
  713.     if (CMT_DecodeMessage(SingleItemMessageTemplate, &reply, &message) !=
  714.         CMTSuccess) {
  715.         goto loser;
  716.     }
  717.     certKey = (CMTItem*)malloc(sizeof(CMTItem));
  718.     if (certKey == NULL) {
  719.         goto loser;
  720.     }
  721.     certKey->len = reply.item.len;
  722.     certKey->data = reply.item.data;
  723.  loser:
  724.     return certKey;
  725. }
  726. /* adds a cert keyed by certKey to the perm DB w/ trustStr info */
  727. CMTStatus CMT_SCAddTempCertToPermDB(PCMT_CONTROL control, CMTItem* certKey,
  728.                                     char* trustStr, char* nickname)
  729. {
  730.     SCAddTempCertToPermDBRequest request;
  731.     CMTItem message = {0, NULL, 0};
  732.     SingleNumMessage reply;
  733.     if ((certKey == NULL) || (trustStr == NULL)) {
  734.         return CMTFailure;
  735.     }
  736.     request.certKey.len = certKey->len;
  737.     request.certKey.data = certKey->data;
  738.     request.trustStr = trustStr;
  739.     request.nickname = nickname;
  740.     if (CMT_EncodeMessage(SCAddTempCertToPermDBRequestTemplate, &message,
  741.                           &request) != CMTSuccess) {
  742.         goto loser;
  743.     }
  744.     message.type = SSM_REQUEST_MESSAGE | SSM_SEC_CFG_ACTION |
  745.         SSM_ADD_TEMP_CERT_TO_DB;
  746.     if (CMT_SendMessage(control, &message) != CMTSuccess) {
  747.         goto loser;
  748.     }
  749.     if (CMT_DecodeMessage(SingleNumMessageTemplate, &reply, &message) !=
  750.         CMTSuccess) {
  751.         goto loser;
  752.     }
  753.     if (reply.value == 0) {
  754.         return CMTSuccess;
  755.     }
  756. loser:
  757.     return CMTFailure;
  758. }
  759. /* deletes a cert (or certs) keyed by certKey from the database */
  760. CMTStatus CMT_SCDeletePermCerts(PCMT_CONTROL control, CMTItem* certKey,
  761.                                 CMBool deleteAll)
  762. {
  763.     SCDeletePermCertsRequest request;
  764.     CMTItem message = {0, NULL, 0};
  765.     SingleNumMessage reply;
  766.     if (certKey == NULL) {
  767.         return CMTFailure;
  768.     }
  769.     request.certKey.len = certKey->len;
  770.     request.certKey.data = certKey->data;
  771.     request.deleteAll = deleteAll;
  772.     if (CMT_EncodeMessage(SCDeletePermCertsRequestTemplate, &message,
  773.                           &request) != CMTSuccess) {
  774.         goto loser;
  775.     }
  776.     message.type = SSM_REQUEST_MESSAGE | SSM_SEC_CFG_ACTION |
  777.         SSM_DELETE_PERM_CERTS;
  778.     if (CMT_SendMessage(control, &message) != CMTSuccess) {
  779.         goto loser;
  780.     }
  781.     if (CMT_DecodeMessage(SingleNumMessageTemplate, &reply, &message) !=
  782.         CMTSuccess) {
  783.         goto loser;
  784.     }
  785.     if (reply.value == 0) {
  786.         return CMTSuccess;
  787.     }
  788. loser:
  789.     return CMTFailure;
  790. }
  791. static CMTItem* CMT_SCFindCertKey(PCMT_CONTROL control, 
  792.                                   SSMSecCfgFindByType subtype, char* name)
  793. {
  794.     CMTItem* certKey = NULL;
  795.     SingleStringMessage request;
  796.     CMTItem message;
  797.     SingleItemMessage reply;
  798.     /* pack the request */
  799.     request.string = name;
  800.     /* encode the request */
  801.     if (CMT_EncodeMessage(SingleStringMessageTemplate, &message, &request) !=
  802.         CMTSuccess) {
  803.         goto loser;
  804.     }
  805.     /* set the message request type */
  806.     message.type = SSM_REQUEST_MESSAGE | SSM_SEC_CFG_ACTION | 
  807.         SSM_FIND_CERT_KEY | subtype;
  808.     /* send the message and get the response */
  809.     if (CMT_SendMessage(control, &message) == CMTFailure) {
  810.         goto loser;
  811.     }
  812.     if (message.type != (SSM_REPLY_OK_MESSAGE | SSM_SEC_CFG_ACTION | 
  813.         SSM_FIND_CERT_KEY | subtype)) {
  814.         goto loser;
  815.     }
  816.     if (CMT_DecodeMessage(SingleItemMessageTemplate, &reply, &message) !=
  817.         CMTSuccess) {
  818.         goto loser;
  819.     }
  820.     /* copy the cert lookup key */
  821.     certKey = (CMTItem*)malloc(sizeof(CMTItem));
  822.     if (certKey == NULL) {
  823.         goto loser;
  824.     }
  825.     certKey->len = reply.item.len;
  826.     certKey->data = reply.item.data;
  827. loser:
  828.     return certKey;
  829. }
  830. /* fetches cert key given nickname */
  831. CMTItem* CMT_SCFindCertKeyByNickname(PCMT_CONTROL control, char* name)
  832. {
  833.     return CMT_SCFindCertKey(control, SSM_FIND_KEY_BY_NICKNAME, name);
  834. }
  835. /* fetches cert key given email address */
  836. CMTItem* CMT_SCFindCertKeyByEmailAddr(PCMT_CONTROL control, char* name)
  837. {
  838.     return CMT_SCFindCertKey(control, SSM_FIND_KEY_BY_EMAIL_ADDR, name);
  839. }
  840. /* fetches cert key given DN */
  841. CMTItem* CMT_SCFindCertKeyByNameString(PCMT_CONTROL control, char* name)
  842. {
  843.     return CMT_SCFindCertKey(control, SSM_FIND_KEY_BY_DN, name);
  844. }
  845. /* packs message that contains the cert key for CertGetProp messages */
  846. static CMTStatus cmt_sc_pack_cert_key(PCMT_CONTROL control, CMTItem* certKey,
  847.                                       SSMSecCfgGetCertPropType subtype,
  848.                                       CMTItem* message)
  849. {
  850.     SingleItemMessage request;
  851.     CMTStatus rv = CMTFailure;
  852.     /* pack the request */
  853.     request.item.len = certKey->len;
  854.     request.item.data = certKey->data;
  855.     /* encode the request */
  856.     rv = CMT_EncodeMessage(SingleItemMessageTemplate, message, &request);
  857.     if (rv != CMTSuccess) {
  858.         return rv;
  859.     }
  860.     /* set the message type */
  861.     message->type = SSM_REQUEST_MESSAGE | SSM_SEC_CFG_ACTION |
  862.         SSM_GET_CERT_PROP_BY_KEY | subtype;
  863.     return CMTSuccess;
  864. }
  865.     
  866. /* fetches string property given cert key */
  867. static char* CMT_SCGetCertPropString(PCMT_CONTROL control, 
  868.                                      CMTItem* certKey, 
  869.                                      SSMSecCfgGetCertPropType subtype)
  870. {
  871.     SingleStringMessage reply;
  872.     CMTItem message;
  873.     char* rv = NULL;
  874.     if (certKey == NULL) {
  875.         goto loser;
  876.     }
  877.     /* create the message */
  878.     if (cmt_sc_pack_cert_key(control, certKey, subtype, &message) != 
  879.         CMTSuccess) {
  880.         goto loser;
  881.     }
  882.     /* send the message and get the response */
  883.     if (CMT_SendMessage(control, &message) == CMTFailure) {
  884.         goto loser;
  885.     }
  886.     if (message.type != (SSM_REPLY_OK_MESSAGE | SSM_SEC_CFG_ACTION |
  887.         SSM_GET_CERT_PROP_BY_KEY)) {
  888.         goto loser;
  889.     }
  890.     /* decode the reply */
  891.     if (CMT_DecodeMessage(SingleStringMessageTemplate, &reply, &message) !=
  892.         CMTSuccess) {
  893.         goto loser;
  894.     }
  895.     rv = reply.string;
  896. loser:
  897.     return rv;
  898. }
  899. static CMTStatus CMT_SCGetCertPropTime(PCMT_CONTROL control,
  900.                                        CMTItem* certKey,
  901.                                        SSMSecCfgGetCertPropType subtype,
  902.                                        CMTime* time)
  903. {
  904.     TimeMessage reply;
  905.     CMTItem message;
  906.     if (certKey == NULL) {
  907.         goto loser;
  908.     }
  909.     /* create the message */
  910.     if (cmt_sc_pack_cert_key(control, certKey, subtype, &message) !=
  911.         CMTSuccess) {
  912.         goto loser;
  913.     }
  914.     /* send the message and get the response */
  915.     if (CMT_SendMessage(control, &message) == CMTFailure) {
  916.         goto loser;
  917.     }
  918.     if (message.type != (SSM_REPLY_OK_MESSAGE | SSM_SEC_CFG_ACTION |
  919.         SSM_GET_CERT_PROP_BY_KEY)) {
  920.         goto loser;
  921.     }
  922.     /* decode the reply */
  923.     if (CMT_DecodeMessage(TimeMessageTemplate, &reply, &message) !=
  924.         CMTSuccess) {
  925.         goto loser;
  926.     }
  927.     time->year = reply.year;
  928.     time->month = reply.month;
  929.     time->day = reply.day;
  930.     time->hour = reply.hour;
  931.     time->minute = reply.minute;
  932.     time->second = reply.second;
  933.     return CMTSuccess;
  934. loser:
  935.     return CMTFailure;
  936. }
  937. /* fetches a related cert key given cert key */
  938. static CMTItem* CMT_SCGetCertPropCertKey(PCMT_CONTROL control, 
  939.                                          CMTItem* certKey,
  940.                                          SSMSecCfgGetCertPropType subtype)
  941. {
  942.     SingleItemMessage reply;
  943.     CMTItem message;
  944.     CMTItem* newKey = NULL;
  945.     
  946.     if (certKey == NULL) {
  947.         goto loser;
  948.     }
  949.     /* create the message */
  950.     if (cmt_sc_pack_cert_key(control, certKey, subtype, &message) !=
  951.         CMTSuccess) {
  952.         goto loser;
  953.     }
  954.     /* send the message and get the response */
  955.     if (CMT_SendMessage(control, &message) == CMTFailure) {
  956.         goto loser;
  957.     }
  958.     if (message.type != (SSM_REPLY_OK_MESSAGE | SSM_SEC_CFG_ACTION |
  959.         SSM_GET_CERT_PROP_BY_KEY)) {
  960.         goto loser;
  961.     }
  962.     /* decode the reply */
  963.     if (CMT_DecodeMessage(SingleItemMessageTemplate, &reply, &message) !=
  964.         CMTSuccess) {
  965.         goto loser;
  966.     }
  967.     newKey = (CMTItem*)malloc(sizeof(CMTItem));
  968.     if (newKey == NULL) {
  969.         goto loser;
  970.     }
  971.     newKey->len = reply.item.len;
  972.     newKey->data = reply.item.data;
  973. loser:
  974.     return newKey;
  975. }
  976. /* fetches cert nickname given cert key */
  977. char* CMT_SCGetCertPropNickname(PCMT_CONTROL control, CMTItem* certKey)
  978. {
  979.     return CMT_SCGetCertPropString(control, certKey, SSM_SECCFG_GET_NICKNAME);
  980. }
  981. /* fetches cert email address given cert key */
  982. char* CMT_SCGetCertPropEmailAddress(PCMT_CONTROL control, CMTItem* certKey)
  983. {
  984.     return CMT_SCGetCertPropString(control, certKey, 
  985.                                    SSM_SECCFG_GET_EMAIL_ADDR);
  986. }
  987. /* fetches cert DN given cert key */
  988. char* CMT_SCGetCertPropDN(PCMT_CONTROL control, CMTItem* certKey)
  989. {
  990.     return CMT_SCGetCertPropString(control, certKey, SSM_SECCFG_GET_DN);
  991. }
  992. /* fetches cert trust given cert key */
  993. char* CMT_SCGetCertPropTrust(PCMT_CONTROL control, CMTItem* certKey)
  994. {
  995.     return CMT_SCGetCertPropString(control, certKey, SSM_SECCFG_GET_TRUST);
  996. }
  997. /* fetches cert serial number given cert key */
  998. char* CMT_SCGetCertPropSerialNumber(PCMT_CONTROL control, CMTItem* certKey)
  999. {
  1000.     return CMT_SCGetCertPropString(control, certKey, 
  1001.                                    SSM_SECCFG_GET_SERIAL_NO);
  1002. }
  1003. /* fetches cert issuer name given cert key */
  1004. char* CMT_SCGetCertPropIssuerName(PCMT_CONTROL control, CMTItem* certKey)
  1005. {
  1006.     return CMT_SCGetCertPropString(control, certKey, 
  1007.                                    SSM_SECCFG_GET_ISSUER);
  1008. }
  1009. /* fetches validity periods as a string given cert key */
  1010. CMTStatus CMT_SCGetCertPropTimeNotBefore(PCMT_CONTROL control, 
  1011.                                          CMTItem* certKey, CMTime* time)
  1012. {
  1013.     return CMT_SCGetCertPropTime(control, certKey, 
  1014.                                  SSM_SECCFG_GET_NOT_BEFORE, time);
  1015. }
  1016. CMTStatus CMT_SCGetCertPropTimeNotAfter(PCMT_CONTROL control, 
  1017.                                         CMTItem* certKey, CMTime* time)
  1018. {
  1019.     return CMT_SCGetCertPropTime(control, certKey, 
  1020.                                  SSM_SECCFG_GET_NOT_AFTER, time);
  1021. }
  1022. /* fetches issuer cert key given cert key */
  1023. CMTItem* CMT_SCGetCertPropIssuerKey(PCMT_CONTROL control, CMTItem* certKey)
  1024. {
  1025.     return CMT_SCGetCertPropCertKey(control, certKey, 
  1026.                                     SSM_SECCFG_GET_ISSUER_KEY);
  1027. }
  1028. /* fetches next subject key given cert key */
  1029. CMTItem* CMT_SCGetCertPropSubjectNext(PCMT_CONTROL control, CMTItem* certKey)
  1030. {
  1031.     return CMT_SCGetCertPropCertKey(control, certKey,
  1032.                                     SSM_SECCFG_GET_SUBJECT_NEXT);
  1033. }
  1034. /* fetches previous subject key given cert key */
  1035. CMTItem* CMT_SCGetCertPropSubjectPrev(PCMT_CONTROL control, CMTItem* certKey)
  1036. {
  1037.     return CMT_SCGetCertPropCertKey(control, certKey,
  1038.                                     SSM_SECCFG_GET_SUBJECT_PREV);
  1039. }
  1040. /* determines whether the cert is in perm db given cert key */
  1041. CMTStatus CMT_SCGetCertPropIsPerm(PCMT_CONTROL control, CMTItem* certKey,
  1042.                                   CMBool* isPerm)
  1043. {
  1044.     CMTItem message;
  1045.     SingleNumMessage reply;
  1046.     if (certKey == NULL) {
  1047.         goto loser;
  1048.     }
  1049.     /* create the message */
  1050.     if (cmt_sc_pack_cert_key(control, certKey, SSM_SECCFG_CERT_IS_PERM,
  1051.                              &message) != CMTSuccess) {
  1052.         goto loser;
  1053.     }
  1054.     /* send the message and get the response */
  1055.     if (CMT_SendMessage(control, &message) == CMTFailure) {
  1056.         goto loser;
  1057.     }
  1058.     if (message.type != (SSM_REPLY_OK_MESSAGE | SSM_SEC_CFG_ACTION |
  1059.         SSM_GET_CERT_PROP_BY_KEY)) {
  1060.         goto loser;
  1061.     }
  1062.     /* decode the reply */
  1063.     if (CMT_DecodeMessage(SingleNumMessageTemplate, &reply, &message) !=
  1064.         CMTSuccess) {
  1065.         goto loser;
  1066.     }
  1067.     if (reply.value) {
  1068.         *isPerm = CM_TRUE;
  1069.     }
  1070.     else {
  1071.         *isPerm = CM_FALSE;
  1072.     }
  1073.     return CMTSuccess;
  1074. loser:
  1075.     return CMTFailure;
  1076. }
  1077. CMTStatus CMT_SCCertIndexEnum(PCMT_CONTROL control, CMInt32 type, 
  1078.                               CMInt32* number, CMCertEnum** list)
  1079. {
  1080.     SingleNumMessage request;
  1081.     SCCertIndexEnumReply reply;
  1082.     CMTItem message;
  1083.     /* initialize these in case of failure */
  1084.     *number = 0;
  1085.     *list = NULL;
  1086.     switch (type) {
  1087.     case 0: /* nickname requested */
  1088.         message.type = SSM_REQUEST_MESSAGE | SSM_SEC_CFG_ACTION |
  1089.             SSM_CERT_INDEX_ENUM | SSM_FIND_KEY_BY_NICKNAME;
  1090.         break;
  1091.     case 1: /* email address requested */
  1092.         message.type = SSM_REQUEST_MESSAGE | SSM_SEC_CFG_ACTION |
  1093.             SSM_CERT_INDEX_ENUM | SSM_FIND_KEY_BY_EMAIL_ADDR;
  1094.         break;
  1095.     case 2: /* DN requested */
  1096.         message.type = SSM_REQUEST_MESSAGE | SSM_SEC_CFG_ACTION |
  1097.             SSM_CERT_INDEX_ENUM | SSM_FIND_KEY_BY_DN;
  1098.         break;
  1099.     default:
  1100.         goto loser;
  1101.         break;
  1102.     }
  1103.     /* pack the request */
  1104.     request.value = 0; /* not important */
  1105.     if (CMT_EncodeMessage(SingleNumMessageTemplate, &message, &request) !=
  1106.         CMTSuccess) {
  1107.         goto loser;
  1108.     }
  1109.     /* send the message and get the response */
  1110.     if (CMT_SendMessage(control, &message) == CMTFailure) {
  1111.         goto loser;
  1112.     }
  1113.     if (message.type != (SSM_REPLY_OK_MESSAGE | SSM_SEC_CFG_ACTION |
  1114.         SSM_CERT_INDEX_ENUM)) {
  1115.         goto loser;
  1116.     }
  1117.     /* decode the reply */
  1118.     if (CMT_DecodeMessage(SCCertIndexEnumReplyTemplate, &reply, &message) !=
  1119.         CMTSuccess) {
  1120.         goto loser;
  1121.     }
  1122.     *number = reply.length;
  1123.     *list = (CMCertEnum*)reply.list;
  1124.     return CMTSuccess;
  1125. loser:
  1126.     return CMTFailure;
  1127. }
  1128. CMTStatus CMT_FindCertExtension(PCMT_CONTROL control, CMUint32 resID, 
  1129.                                 CMUint32 extension, CMTItem *extValue)
  1130. {
  1131.     GetCertExtension request;
  1132.     SingleItemMessage reply;
  1133.     CMTItem message;
  1134.     request.resID = resID;
  1135.     request.extension = extension;
  1136.     message.type = SSM_REQUEST_MESSAGE | SSM_CERT_ACTION | SSM_EXTENSION_VALUE;
  1137.     if (CMT_EncodeMessage(GetCertExtensionTemplate, 
  1138.                           &message, &request) != CMTSuccess) {
  1139.         goto loser;
  1140.     }
  1141.     if (CMT_SendMessage(control, &message) != CMTSuccess) {
  1142.         goto loser;
  1143.     }
  1144.     if (message.type != (SSM_REPLY_OK_MESSAGE | 
  1145.                          SSM_CERT_ACTION      |
  1146.                          SSM_EXTENSION_VALUE)) {
  1147.         goto loser;
  1148.     }
  1149.     if (CMT_DecodeMessage(SingleItemMessageTemplate, 
  1150.                           &reply, &message) != CMTSuccess) {
  1151.         goto loser;
  1152.     }
  1153.     extValue->type = 0;
  1154.     extValue->data = reply.item.data;
  1155.     extValue->len  = reply.item.len;
  1156.     return CMTSuccess;
  1157.  loser:
  1158.     return CMTFailure;
  1159. }
  1160. CMTStatus 
  1161. CMT_HTMLCertInfo(PCMT_CONTROL control, CMUint32 certID, CMBool showImages,
  1162.                  CMBool showIssuer, char **retHtml)
  1163. {
  1164.     HTMLCertInfoRequest request;
  1165.     SingleStringMessage reply;
  1166.     CMTItem message;
  1167.     if (retHtml == NULL) {
  1168.         return CMTFailure;
  1169.     }
  1170.     request.certID     = certID;
  1171.     request.showImages = showImages;
  1172.     request.showIssuer = showIssuer;
  1173.     if (CMT_EncodeMessage(HTMLCertInfoRequestTemplate, 
  1174.                           &message, &request) != CMTSuccess) {
  1175.         goto loser;
  1176.     }
  1177.     message.type = SSM_REQUEST_MESSAGE | SSM_CERT_ACTION | SSM_HTML_INFO;
  1178.     if (CMT_SendMessage(control, &message) != CMTSuccess) {
  1179.         goto loser;
  1180.     }
  1181.     if (message.type != (SSM_REPLY_OK_MESSAGE | SSM_CERT_ACTION | 
  1182.                          SSM_HTML_INFO)) {
  1183.         goto loser;
  1184.     }
  1185.     if (CMT_DecodeMessage(SingleStringMessageTemplate, 
  1186.                           &reply, &message) != CMTSuccess) {
  1187.         goto loser;
  1188.     }
  1189.     *retHtml = reply.string;
  1190.     return CMTSuccess;
  1191.  loser:
  1192.     return CMTFailure;
  1193. }