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

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. /*************************************************************************
  35.  * Only server-side message functions are provided: Parse functions for 
  36.  * request messages and Pack functions for reply messages. 
  37.  *
  38.  * Parse functions accept a ptr to the "blob" of data received from the 
  39.  * network and return fields of the message, numerals in host-order, 
  40.  * strings as C-style character strings. If everything goes well,
  41.  * blob of data is freed and SUCCESS is returned, otherwise an error returned
  42.  * and data left intact. Caller may pass NULL ptrs for the fields s/he is
  43.  * not interested in. 
  44.  *
  45.  * Pack functions take all the info to construct a message and fill in a 
  46.  * ptr to the "blob" of data to be sent. Return size of the "blob" or 0
  47.  * if something goes wrong. All fields of the message must be supplied, 
  48.  * otherwise an error is returned.
  49.  *
  50.  * All functions set NSPR errors when necessary. 
  51.  * Caller is responsible for freeing returned values.
  52.  ************************************************************************/
  53. #include "protocolf.h"
  54. #include "rsrcids.h"
  55. #include "nspr.h"
  56. /* Utility functions to handle generic requests/replies */
  57. SSMPRStatus SSM_ParseSingleNumRequest(void *request,
  58.                                       SSMPRUint32 *result)
  59. {
  60.     PRStatus rv = PR_SUCCESS;
  61.     
  62.     if (!request) 
  63.         rv = PR_INVALID_ARGUMENT_ERROR;
  64.     else if (result) 
  65.         *result = SSMPR_ntohl(*(SSMPRUint32 *)request);
  66.     /* ### mwelch Don't free this here, because the message-specific
  67.        handlers will free this for us. */
  68.     /*    if (request)
  69.         PR_Free(request);*/
  70.     return rv;
  71. }
  72. SSMPRInt32 SSM_PackSingleNumReply(void **reply, SSMPRUint32 num)
  73. {
  74.     SSMPRStatus rv = PR_SUCCESS;
  75.     if (!reply)
  76.         rv = SSMPR_INVALID_ARGUMENT_ERROR;
  77.     else
  78.     {
  79.         /* allocate memory for blob of data */
  80.         *reply = (void *)SSMPORT_ZAlloc(sizeof(SSMPRUint32));
  81.         if (!*reply) 
  82.             rv = SSMPR_OUT_OF_MEMORY_ERROR;
  83.     }
  84.     if (rv == PR_SUCCESS)
  85.     {
  86.         *(SSMPRInt32 *)*reply = SSMPR_htonl(num);
  87.         return sizeof(SSMPRUint32);
  88.     }
  89.     else
  90.     {
  91.         SSMPORT_SetError(rv);
  92.         return 0;
  93.     }    
  94. }
  95. /* Initial messages - establishing connection */
  96. SSMPRStatus SSM_ParseHelloRequest(void * helloRequest, 
  97.                                   SSMPRUint32 * version, 
  98.                                   PRBool *doesUI,
  99.                                   PRInt32 * policyType,
  100.                                   SSMPRUint32 * profileLen, 
  101.                                   char ** profile)
  102. {
  103.   void * curptr = helloRequest;
  104.   SSMPRStatus rv = SSMPR_SUCCESS;
  105.   if (!helloRequest) {
  106.     rv = PR_INVALID_ARGUMENT_ERROR;
  107.     goto loser;
  108.   }
  109.   
  110.   /* read and store protocol version */
  111.   if (version) 
  112.     *version = SSMPR_ntohl(*((SSMPRUint32 *)curptr));
  113.   curptr = (SSMPRUint32 *)curptr + 1;
  114.   if (policyType)
  115.       *policyType = PR_ntohl(*((PRInt32 *)curptr));
  116.   curptr = (SSMPRUint32 *)curptr + 1;
  117.   if (doesUI)
  118.       *doesUI = PR_ntohl(*((SSMPRInt32 *)curptr));
  119.   curptr = (SSMPRUint32 *)curptr + 1;
  120.   if (profile) { 
  121.     *profile = NULL;
  122.     /* read and store profile name that client uses */
  123.     rv = SSM_SSMStringToString(profile, NULL, (SSMString *)curptr);
  124.     if (rv != SSMPR_SUCCESS && *profile)
  125.       SSMPORT_Free(*profile);
  126.   }
  127. loser:
  128.   if (helloRequest)
  129.   SSMPORT_Free(helloRequest);
  130.   return rv;
  131. }
  132. SSMPRInt32 SSM_PackHelloReply(void ** helloReply, SSMPRInt32 result, 
  133.       SSMPRUint32 sessionID, SSMPRUint32 version, 
  134.       SSMPRUint32 httpPort, 
  135.       SSMPRUint32 nonceLength, char * nonce,
  136.       SSMPolicyType policy)
  137. {
  138.   SSMPRInt32 blobSize;
  139.   void * curptr, * nonceStr;
  140.   SSMPRStatus rv;
  141.   if (!helloReply || !nonce || !*nonce || policy == ssmUnknownPolicy) { 
  142.     rv = PR_INVALID_ARGUMENT_ERROR;
  143.     goto loser;
  144.   }
  145.   blobSize = sizeof(SSMPRInt32)+ sizeof(SSMPRUint32) * 5 + 
  146.     SSMSTRING_PADDED_LENGTH(strlen(nonce));
  147.   curptr = (void *)SSMPORT_ZAlloc(blobSize);
  148.   if (!curptr) { 
  149.     rv = PR_OUT_OF_MEMORY_ERROR;
  150.     *helloReply = NULL;
  151.     goto loser;
  152.   }
  153.   *helloReply = curptr;
  154.   *(SSMPRInt32 *)curptr = SSMPR_htonl(result);
  155.   curptr = (SSMPRInt32 *)curptr + 1;
  156.   *(SSMPRUint32 *)curptr = SSMPR_htonl(sessionID); 
  157.   curptr = (SSMPRUint32 *)curptr + 1;
  158.   *(SSMPRUint32 *)curptr = SSMPR_htonl(version); 
  159.   curptr = (SSMPRUint32 *)curptr + 1;
  160.    *(SSMPRUint32 *)curptr = SSMPR_htonl(httpPort); 
  161.   curptr = (SSMPRUint32 *)curptr + 1;
  162.    *(SSMPRUint32 *)curptr = SSMPR_htonl(policy); 
  163.   curptr = (SSMPRUint32 *)curptr + 1;
  164.   
  165.   rv = SSM_StringToSSMString((SSMString **)&nonceStr, 0, nonce);
  166.   if (rv != SSMPR_SUCCESS) { 
  167.     if (nonceStr) SSMPORT_Free(nonceStr); /* free string */
  168.     goto loser;
  169.  }
  170.   memcpy(curptr, nonceStr, SSM_SIZEOF_STRING(*(SSMString *)nonceStr));
  171.   SSMPORT_Free(nonceStr);
  172.   
  173.   return blobSize;
  174. loser:
  175.   if (*helloReply)
  176. PR_Free(*helloReply);
  177.   return 0;
  178. }
  179. /* Handle data connection messages */
  180. /* SSL data connection request */
  181. SSMPRStatus SSM_ParseSSLDataConnectionRequest(void *sslRequest, 
  182.       SSMPRUint32 * flags, 
  183.       SSMPRUint32 * port, 
  184.       SSMPRUint32 * hostIPLen, 
  185.       char ** hostIP, 
  186.       SSMPRUint32 * hostNameLen,
  187.       char ** hostName)
  188. {
  189.   SSMPRStatus rv = SSMPR_SUCCESS;
  190.   void * curptr;
  191.   
  192.   if (!sslRequest) { 
  193.     rv = PR_INVALID_ARGUMENT_ERROR;
  194.     goto loser;
  195.   }
  196.   curptr = sslRequest;
  197.   if (flags) *flags = SSMPR_ntohl(*(SSMPRUint32 *)curptr);
  198.   curptr = (SSMPRUint32 *)curptr + 1;
  199.   if (port) *port = SSMPR_ntohl(*(SSMPRUint32 *)curptr);
  200.   curptr = (SSMPRUint32 *)curptr + 1;
  201.   
  202.   if (hostIP) { 
  203.     *hostIP = NULL;
  204.     /* read and store hostIP */
  205.     rv = SSM_SSMStringToString(hostIP,  NULL, (SSMString *)curptr);
  206.     if (rv != SSMPR_SUCCESS)  
  207.       goto loser; 
  208.   }
  209.   curptr = (char *)curptr + SSM_SIZEOF_STRING(*(SSMString *)curptr);
  210.   if (hostName) { 
  211.     *hostName = NULL;
  212.     /* read and store hostName */
  213.     rv = SSM_SSMStringToString(hostName,  NULL, (SSMString *)curptr);
  214.     if (rv != SSMPR_SUCCESS)  
  215.          goto loser;
  216.   }
  217. goto done;
  218. loser:
  219.     if (hostName && *hostName) 
  220. PR_Free(*hostName);
  221.     if (hostIP && *hostIP)
  222. PR_Free(*hostIP);
  223. done:
  224.   if (sslRequest)
  225.      SSMPORT_Free(sslRequest);
  226.   return rv;
  227. }
  228. /* Hash stream data connection request */
  229. SSMPRStatus SSM_ParseHashStreamRequest(void * hashStreamRequest, 
  230.        SSMPRUint32 * type)
  231. {
  232.  PRStatus rv = PR_SUCCESS;
  233.   if (!hashStreamRequest) {
  234.     rv = PR_INVALID_ARGUMENT_ERROR;
  235.     goto loser;
  236.   }
  237.   if (type) *type = SSMPR_ntohl(*(SSMPRUint32 *)hashStreamRequest);
  238.  loser:
  239.   if (hashStreamRequest) 
  240.      SSMPORT_Free(hashStreamRequest);
  241.   return rv;
  242. }
  243. /* Messages to initiate PKCS7 data connection */
  244. /* PKCS7DecodeRequest message has no data */ 
  245. /* Create PKCS7 encode connection.  Needs a content info */
  246. SSMPRStatus SSM_ParseP7EncodeConnectionRequest(void *request,
  247.        SSMPRUint32 *ciRID)
  248. {
  249.     return SSM_ParseSingleNumRequest(request, ciRID);
  250. }
  251. /* Create data connection reply - same for all types of data connections */
  252. SSMPRInt32 SSM_PackDataConnectionReply(void ** sslReply, 
  253.        SSMPRInt32 result, 
  254.        SSMPRUint32 connID, 
  255.        SSMPRUint32 port)
  256. {
  257.   void * curptr = NULL;
  258.   SSMPRInt32 blobSize;
  259.   if (!sslReply) {
  260.     SSMPORT_SetError(SSMPR_INVALID_ARGUMENT_ERROR);
  261.     return 0;
  262.   }
  263.   
  264.   blobSize = sizeof(SSMPRInt32) + sizeof(SSMPRUint32)*2;
  265.   /* allocate space for the SSLDataConnectionReply "blob" */
  266.   curptr = (void *)SSMPORT_ZAlloc(blobSize);
  267.   if (!curptr) { 
  268.     SSMPORT_SetError(SSMPR_OUT_OF_MEMORY_ERROR);
  269.     *sslReply = NULL;
  270.     return 0;
  271.   }
  272.   *sslReply = curptr;
  273.   *(SSMPRInt32 *)curptr = SSMPR_htonl(result);
  274.   curptr = (SSMPRInt32 *)curptr + 1;
  275.   *(SSMPRUint32 *)curptr = SSMPR_htonl(connID);
  276.   curptr = (SSMPRUint32 *)curptr + 1;
  277.   *(SSMPRUint32 *)curptr = SSMPR_htonl(port);
  278.   return blobSize;
  279. }
  280. /* Messages to create SocketStatus resource */
  281. SSMPRStatus SSM_ParseSSLSocketStatusRequest(void * statusRequest, 
  282.     SSMPRUint32 * connID)
  283.   PRStatus rv = PR_SUCCESS;
  284.   if (!statusRequest ) { 
  285.     rv = PR_INVALID_ARGUMENT_ERROR;
  286.     goto loser;
  287.   }
  288.   if (connID) *connID = SSMPR_ntohl(*((SSMPRUint32 *)statusRequest));
  289. loser:
  290.   if (statusRequest)
  291.     SSMPORT_Free(statusRequest);
  292.   return rv;
  293. }   
  294. SSMPRInt32 SSM_PackSSLSocketStatusReply(void ** statusReply, 
  295. SSMPRInt32 result, 
  296. SSMPRUint32 resourceID)
  297. {
  298.   SSMPRInt32 blobSize;
  299.   void * curptr;
  300.   
  301.   if (!statusReply){ 
  302.     SSMPORT_SetError(SSMPR_INVALID_ARGUMENT_ERROR);
  303.     return 0;
  304.   }
  305.   /* allocate memory for blob of data */
  306.   blobSize = sizeof(SSMPRUint32) + sizeof(SSMPRInt32);
  307.   curptr = (void *)SSMPORT_ZAlloc(blobSize);
  308.   if (!curptr) { 
  309.     SSMPORT_SetError(SSMPR_OUT_OF_MEMORY_ERROR);
  310.     *statusReply = NULL;
  311.     return 0;
  312.   }
  313.   *statusReply = curptr;
  314.   *(SSMPRInt32 *)curptr = SSMPR_htonl(result);
  315.   curptr = (SSMPRInt32 *)curptr + 1;
  316.   *(SSMPRUint32 *)curptr = SSMPR_htonl(resourceID); 
  317.   
  318.   return blobSize;
  319. }
  320. /* UI event message - server initiated */
  321. SSMPRInt32 SSM_PackUIEvent(void ** eventData, SSMPRUint32 resourceID, 
  322.    SSMPRUint32 width, SSMPRUint32 height, 
  323.    SSMPRUint32 urlLen, char * url)
  324. {
  325.   void * curptr, * tmpStr;
  326.   SSMPRInt32 blobSize;
  327.   SSMPRStatus rv;
  328.   if (!eventData){ 
  329.     SSMPORT_SetError(SSMPR_INVALID_ARGUMENT_ERROR);
  330.     return 0;
  331.   }
  332.   /* allocate memory for blob of data */
  333.   blobSize = sizeof(SSMPRUint32) * 4 + SSMSTRING_PADDED_LENGTH(strlen(url));
  334.   curptr = (void *)SSMPORT_ZAlloc(blobSize);
  335.   if (!curptr) { 
  336.     SSMPORT_SetError(SSMPR_OUT_OF_MEMORY_ERROR);
  337.     *eventData = NULL;
  338.     return 0;
  339.   }
  340.   *eventData = curptr;
  341.   *(SSMPRUint32 *)curptr = SSMPR_htonl(resourceID);
  342.   curptr = (SSMPRUint32 *)curptr + 1;
  343.   *(SSMPRUint32 *)curptr = SSMPR_htonl(width);
  344.   curptr = (SSMPRUint32 *)curptr + 1;
  345.   *(SSMPRUint32 *)curptr = SSMPR_htonl(height);
  346.   curptr = (SSMPRUint32 *)curptr + 1;
  347.   
  348.   /* copy URL string into the blob */
  349.   rv = SSM_StringToSSMString((SSMString **)&tmpStr, 0, url);
  350.   if (rv != SSMPR_SUCCESS) { 
  351.     if (tmpStr) SSMPORT_Free(tmpStr); /* free string */
  352.     SSMPORT_Free(*eventData);            /* free blob   */
  353.     *eventData = NULL;
  354.     return 0;
  355.   }
  356.   memcpy(curptr, tmpStr, SSM_SIZEOF_STRING(*(SSMString *)tmpStr));
  357.   SSMPORT_Free(tmpStr);
  358.   
  359.   return blobSize;
  360. }
  361. SSMPRInt32 SSM_PackTaskCompletedEvent(void **event, SSMPRUint32 resourceID, 
  362.                                       SSMPRUint32 numTasks, 
  363.                                       SSMPRUint32 result)
  364. {
  365.   void * curptr;
  366.   SSMPRInt32 blobSize;
  367.   if (!event){ 
  368.     SSMPORT_SetError(SSMPR_INVALID_ARGUMENT_ERROR);
  369.     return 0;
  370.   }
  371.   /* allocate memory for blob of data */
  372.   blobSize = sizeof(SSMPRUint32) * 3;
  373.   curptr = (void *)SSMPORT_ZAlloc(blobSize);
  374.   if (!curptr) { 
  375.     SSMPORT_SetError(SSMPR_OUT_OF_MEMORY_ERROR);
  376.     *event = NULL;
  377.     return 0;
  378.   }
  379.   *event = curptr;
  380.   *(SSMPRUint32 *)curptr = SSMPR_htonl(resourceID);
  381.   curptr = (SSMPRUint32 *)curptr + 1;
  382.   *(SSMPRUint32 *)curptr = SSMPR_htonl(numTasks);
  383.   curptr = (SSMPRUint32 *)curptr + 1;
  384.   *(SSMPRUint32 *)curptr = SSMPR_htonl(result);
  385.   
  386.   return blobSize;
  387. }
  388. /* Handle verify signature messages */
  389. SSMPRStatus SSM_ParseVerifyRawSigRequest(void * verifyRawSigRequest, 
  390.  SSMPRUint32 * algorithmID,
  391.  SSMPRUint32 *paramsLen,
  392.  unsigned char ** params,
  393.  SSMPRUint32 * pubKeyLen,
  394.  unsigned char ** pubKey,
  395.  SSMPRUint32 * hashLen,
  396.  unsigned char ** hash,
  397.  SSMPRUint32 * signatureLen,
  398.  unsigned char ** signature)
  399. {
  400.   void * curptr = verifyRawSigRequest;
  401.   SSMPRStatus rv = SSMPR_SUCCESS;
  402.   if (!verifyRawSigRequest) { 
  403.     rv = PR_INVALID_ARGUMENT_ERROR;
  404.     goto loser;
  405.   }
  406.   if (algorithmID) *algorithmID = SSMPR_ntohl(*(SSMPRUint32 *)curptr);
  407.   curptr = (SSMPRUint32 *)curptr + 1;
  408.  
  409.   if (params) { 
  410.      *params = NULL;
  411.      /* read and store cipher */
  412.      rv = SSM_SSMStringToString((char **)params,  NULL, (SSMString *)curptr);
  413.      if (rv != SSMPR_SUCCESS) 
  414.        goto loser;
  415.   }  
  416.   curptr = (char *)curptr + SSM_SIZEOF_STRING(*(SSMString *)curptr);
  417.   if (pubKey) { 
  418.      *pubKey = NULL;
  419.      /* read and store cipher */
  420.      rv = SSM_SSMStringToString((char **)pubKey,  NULL, (SSMString *)curptr);
  421.      if (rv != SSMPR_SUCCESS) 
  422.        goto loser;
  423.   }
  424.   curptr = (char *)curptr + SSM_SIZEOF_STRING(*(SSMString *)curptr);
  425.   if (signature) { 
  426.     *signature = NULL;
  427.     /* read and store cipher */
  428.     rv = SSM_SSMStringToString((char **)signature,  NULL, (SSMString *)curptr);
  429.     if (rv != SSMPR_SUCCESS) 
  430.       goto loser;  
  431.   }
  432.  goto done;
  433.  
  434. loser:
  435.   if (params && *params) 
  436.     SSMPORT_Free(*params);
  437.   if (pubKey && *pubKey) 
  438.     SSMPORT_Free(*pubKey);
  439.   if (signature && *signature) 
  440.     SSMPORT_Free(*signature);
  441. done:
  442.   if (verifyRawSigRequest)
  443.      PR_Free(verifyRawSigRequest); 
  444.   return rv;
  445. }
  446. SSMPRInt32 SSM_PackVerifyRawSigReply(void ** verifyRawSigReply, 
  447.      SSMPRInt32 result)
  448. {
  449.   SSMPRInt32 blobSize;
  450.   void * curptr;
  451.   if (!verifyRawSigReply) {
  452.     SSMPORT_SetError(SSMPR_INVALID_ARGUMENT_ERROR);
  453.     return 0;
  454.   }
  455.   
  456.   *verifyRawSigReply = NULL;
  457.   blobSize = sizeof(SSMPRInt32);
  458.   /* allocate space for the verifyRawSigReply "blob" */
  459.   curptr = (void *)SSMPORT_ZAlloc(blobSize);
  460.   if (!curptr) { 
  461.     SSMPORT_SetError(SSMPR_OUT_OF_MEMORY_ERROR);
  462.     return 0;
  463.   }
  464.   *verifyRawSigReply = curptr;
  465.   *(SSMPRInt32 *)curptr = SSMPR_htonl(result);
  466.   
  467.   return blobSize;
  468. }
  469. SSMPRStatus SSM_ParseVerifyDetachedSigRequest(void * verifyDetachedSigRequest,
  470.       SSMPRInt32 * pkcs7ContentID,
  471.       SSMPRInt32 * certUsage,
  472.       SSMPRInt32 * hashAlgID,
  473.       SSMPRUint32 * keepCert,
  474.       SSMPRUint32 * hashLen,
  475.       unsigned char ** hash)
  476. {
  477.   void * curptr = verifyDetachedSigRequest;
  478.   SSMPRStatus rv = SSMPR_SUCCESS;
  479.   if (!verifyDetachedSigRequest) { 
  480.     rv = PR_INVALID_ARGUMENT_ERROR;
  481.     goto loser;
  482.   }
  483.   if (pkcs7ContentID) *pkcs7ContentID = SSMPR_ntohl(*(SSMPRUint32 *)curptr);
  484.   curptr = (SSMPRUint32 *)curptr + 1;
  485.   
  486.   if (certUsage) *certUsage = SSMPR_ntohl(*(SSMPRInt32 *)curptr);
  487.   curptr = (SSMPRInt32 *)curptr + 1;
  488.   
  489.   if (hashAlgID) *hashAlgID = SSMPR_ntohl(*(SSMPRInt32 *)curptr);
  490.   curptr = (SSMPRInt32 *)curptr + 1;
  491.   
  492.   if (keepCert) *keepCert = SSMPR_ntohl(*(SSMPRUint32 *)curptr);
  493.   curptr = (SSMPRUint32 *)curptr + 1;  
  494.  
  495.   if (hash) { 
  496.      *hash = NULL;
  497.      /* read and store cipher */
  498.      rv = SSM_SSMStringToString((char **)hash,  (PRInt32 *)hashLen, (SSMString *)curptr);
  499.      if (rv != SSMPR_SUCCESS)  
  500.          goto loser;
  501.   }
  502.   goto done;
  503. loser:
  504.   if (hash && *hash)
  505.      PR_Free(*hash); 
  506. done: 
  507.   if (verifyDetachedSigRequest) 
  508.      PR_Free(verifyDetachedSigRequest);
  509.   return rv;
  510. }
  511. SSMPRInt32 SSM_PackVerifyDetachedSigReply(void ** verifyDetachedSigReply, 
  512.      SSMPRInt32 result)
  513. {
  514.   SSMPRInt32 blobSize;
  515.   void * curptr;
  516.   if (!verifyDetachedSigReply) {
  517.     SSMPORT_SetError(SSMPR_INVALID_ARGUMENT_ERROR);
  518.     return 0;
  519.   }  
  520.   *verifyDetachedSigReply = NULL;
  521.   blobSize = sizeof(SSMPRInt32);
  522.   /* allocate space for the helloRequest "blob" */
  523.   curptr = (void *)SSMPORT_ZAlloc(blobSize);
  524.   if (!curptr) { 
  525.     SSMPORT_SetError(SSMPR_OUT_OF_MEMORY_ERROR);
  526.     return 0;
  527.   }
  528.   *verifyDetachedSigReply = curptr;
  529.   *(SSMPRInt32 *)curptr = SSMPR_htonl(result);
  530.   
  531.   return blobSize;
  532. }
  533. /* Messages for the resource management */
  534. SSMPRStatus SSM_ParseCreateSignedRequest(void *request,
  535.                                          SSMPRInt32 *scertRID,
  536.                                          SSMPRInt32 *ecertRID,
  537.                                          SSMPRUint32 *dig_alg,
  538.                                          SECItem **digest)
  539. {
  540.     unsigned char *curPtr = (unsigned char *) request;
  541.     SSMPRStatus rv;
  542.     if (!request) {
  543.         SSMPORT_SetError(SSMPR_INVALID_ARGUMENT_ERROR);
  544.         return SSMPR_FAILURE;
  545.     }
  546.     *scertRID = SSMPR_ntohl(*(SSMPRInt32*)curPtr);
  547.     curPtr += sizeof(SSMPRInt32);
  548.     *ecertRID = SSMPR_ntohl(*(SSMPRInt32*)curPtr);
  549.     curPtr += sizeof(SSMPRInt32);
  550.     *dig_alg = SSMPR_ntohl(*(SSMPRUint32*)curPtr);
  551.     curPtr += sizeof(SSMPRUint32);
  552.     *digest = PR_NEWZAP(SECItem);
  553.     if (*digest == NULL)
  554.         goto loser;
  555.     rv = SSM_SSMStringToString(&(*digest)->data, &(*digest)->len,
  556.                                (SSMString *) curPtr);
  557.     if (rv != SSMPR_SUCCESS)
  558.         goto loser;
  559.     return PR_SUCCESS;
  560. loser:
  561.     return PR_FAILURE;
  562. }
  563. SSMPRInt32 SSM_PackCreateSignedReply(void **reply, SSMPRInt32 ciRID,
  564.                                      SSMPRUint32 result)
  565. {
  566.     SSMPRInt32     blobSize;
  567.     unsigned char *curPtr;
  568.     
  569.     blobSize = sizeof (SSMPRInt32) + sizeof(SSMPRUint32);
  570.     *reply = curPtr = PORT_ZAlloc(blobSize);
  571.     if (curPtr == NULL) {
  572.         SSMPORT_SetError(SSMPR_OUT_OF_MEMORY_ERROR);
  573.         return 0;
  574.     }
  575.     *((SSMPRInt32*)curPtr) = SSMPR_htonl(ciRID);
  576.     curPtr += sizeof(SSMPRInt32);
  577.     *((SSMPRInt32*)curPtr) = SSMPR_htonl(result);
  578.     
  579.     return blobSize;
  580. }
  581. SSMPRStatus SSM_ParseCreateEncryptedRequest(void *request,
  582.                                             SSMPRInt32 *scertRID,
  583.                                             SSMPRInt32 *nrcerts,
  584.                                             SSMPRInt32 **rcertRIDs)
  585. {
  586.     unsigned char *curPtr = (unsigned char *) request;
  587.     SSMPRStatus rv;
  588.     SSMPRInt32 ncerts;
  589.     int i;
  590.     if (!request) {
  591.         SSMPORT_SetError(SSMPR_INVALID_ARGUMENT_ERROR);
  592.         return SSMPR_FAILURE;
  593.     }
  594.     *scertRID = SSMPR_ntohl(*(SSMPRInt32*)curPtr);
  595.     curPtr += sizeof(SSMPRInt32);
  596.     ncerts = SSMPR_ntohl(*(SSMPRInt32*)curPtr);
  597.     *rcertRIDs = PR_Calloc(ncerts+1, sizeof(SSMPRInt32));
  598.     curPtr += sizeof(SSMPRInt32);
  599.     for (i = 0; i < ncerts; i++) {
  600.         (*rcertRIDs)[i] = SSMPR_ntohl(*(SSMPRInt32*)curPtr);
  601.         curPtr += sizeof(SSMPRInt32);
  602.     }
  603.     *nrcerts = ncerts;
  604.     return SSMPR_SUCCESS;
  605. }
  606. SSMPRInt32 SSM_PackCreateEncryptedReply(void **reply, SSMPRInt32 ciRID,
  607.                                         SSMPRUint32 result)
  608. {
  609.     SSMPRInt32     blobSize;
  610.     unsigned char *curPtr;
  611.     
  612.     blobSize = sizeof (SSMPRInt32) + sizeof(SSMPRUint32);
  613.     *reply = curPtr = PORT_ZAlloc(blobSize);
  614.     if (curPtr == NULL) {
  615.         SSMPORT_SetError(SSMPR_OUT_OF_MEMORY_ERROR);
  616.         return 0;
  617.     }
  618.     *((SSMPRInt32*)curPtr) = SSMPR_htonl(ciRID);
  619.     curPtr += sizeof(SSMPRInt32);
  620.     *((SSMPRInt32*)curPtr) = SSMPR_htonl(result);
  621.     
  622.     return blobSize;
  623. }
  624. SSMPRStatus SSM_ParseCreateResourceRequest(void *request,
  625.                                            SSMPRUint32 *type,
  626.                                            unsigned char **params,
  627.                                            SSMPRUint32 *paramLen)
  628. {
  629.     unsigned char *curPtr = (unsigned char*)request;
  630.     SSMPRStatus    rv     = SSMPR_SUCCESS;
  631.     if (!request)
  632.     {
  633.         SSMPORT_SetError(SSMPR_INVALID_ARGUMENT_ERROR);
  634.         return SSMPR_FAILURE;
  635.     }
  636.     /* Get stuff out. */
  637.     if (type)
  638.         *type = SSMPR_ntohl(*((SSMPRInt32*)curPtr));
  639.     curPtr += sizeof(SSMPRInt32);
  640.     if (params)
  641.         rv = SSM_SSMStringToString((char **) params, (int*) paramLen,
  642.                                    (SSMString *) curPtr);
  643.     return rv;
  644. }
  645. SSMPRStatus SSM_PackCreateResourceReply(void **reply, SSMPRStatus rv,
  646.                                         SSMPRUint32 resID)
  647. {
  648.     SSMPRInt32     blobSize;
  649.     unsigned char *curPtr;
  650.     
  651.     blobSize = sizeof (SSMPRInt32) + sizeof(SSMPRUint32);
  652.     *reply = curPtr = PORT_ZAlloc(blobSize);
  653.     if (curPtr == NULL) {
  654.         SSMPORT_SetError(SSMPR_OUT_OF_MEMORY_ERROR);
  655.         return 0;
  656.     }
  657.     *((SSMPRInt32*)curPtr) = SSMPR_htonl(rv);
  658.     curPtr += sizeof(SSMPRInt32);
  659.     *((SSMPRInt32*)curPtr) = SSMPR_htonl(resID);
  660.     
  661.     return blobSize;
  662. }
  663. SSMPRStatus SSM_ParseDuplicateResourceRequest(void *request,
  664.       SSMPRUint32 *resourceID)
  665. {
  666.     return SSM_ParseSingleNumRequest(request, resourceID);
  667. }
  668.  
  669. SSMPRInt32 SSM_PackDuplicateResourceReply(void ** reply, SSMPRInt32 result,
  670.   SSMPRUint32 resID)
  671. {
  672.     SSMPRInt32     blobSize;
  673.     unsigned char *curPtr;
  674.     
  675.     blobSize = sizeof (SSMPRInt32) + sizeof(SSMPRUint32);
  676.     *reply = curPtr = PORT_ZAlloc(blobSize);
  677.     if (curPtr == NULL) {
  678.         SSMPORT_SetError(SSMPR_OUT_OF_MEMORY_ERROR);
  679.         return 0;
  680.     }
  681.     *((SSMPRInt32*)curPtr) = SSMPR_htonl(result);
  682.     curPtr += sizeof(SSMPRInt32);
  683.     *((SSMPRInt32*)curPtr) = SSMPR_htonl(resID);
  684.     
  685.     return blobSize;
  686. }
  687. SSMPRStatus SSM_ParseGetAttribRequest(void * getAttribRequest, 
  688.       SSMPRUint32 * resourceID, 
  689.       SSMPRUint32 * fieldID)
  690.   void * curptr = getAttribRequest; 
  691.   PRStatus rv = PR_SUCCESS;
  692.   if (!getAttribRequest) { 
  693.     rv = PR_INVALID_ARGUMENT_ERROR;
  694.     goto loser;
  695.   }
  696.   if (resourceID) *resourceID = SSMPR_ntohl(*(SSMPRUint32 *)curptr);
  697.   curptr = (SSMPRUint32 *)curptr + 1;
  698.   
  699.   if (fieldID) *fieldID = SSMPR_ntohl(*(SSMPRInt32 *)curptr);
  700.   curptr = (SSMPRInt32 *)curptr + 1;
  701.   
  702. loser:
  703.   if (getAttribRequest)
  704.      PR_Free(getAttribRequest);
  705.   return rv;
  706. }
  707. SSMPRInt32 SSM_PackGetAttribReply(void **getAttribReply,
  708.   SSMPRInt32 result,
  709.   SSMAttributeValue *value)
  710. {
  711.   SSMPRInt32 blobSize, fieldlength;
  712.   void * curptr;
  713.   if (!getAttribReply) {
  714.     SSMPORT_SetError(SSMPR_INVALID_ARGUMENT_ERROR);
  715.     return 0;
  716.   }
  717.   *getAttribReply = NULL;
  718.   
  719.   /* Calculate length of the field value. Binary length (fielddatalen)
  720. takes precedence over using strlen(). */
  721.   fieldlength = (value->type == SSM_STRING_ATTRIBUTE) ? 
  722.   PR_ntohl(SSMSTRING_PADDED_LENGTH(value->u.string->m_length)) : 0;
  723.   fieldlength += sizeof(SSMPRUint32);
  724.   blobSize = sizeof(SSMPRInt32) + fieldlength;
  725.   /* allocate space for the getAttribReply "blob" */
  726.   curptr = (void *)SSMPORT_ZAlloc(blobSize);
  727.   if (!curptr) { 
  728.     SSMPORT_SetError(SSMPR_OUT_OF_MEMORY_ERROR);
  729.     return 0;
  730.   }
  731.   * getAttribReply = curptr;
  732.   *(SSMPRInt32 *)curptr = SSMPR_htonl(result);
  733.   curptr = (SSMPRInt32 *)curptr + 1;
  734.   switch(value->type) {
  735.    case SSM_STRING_ATTRIBUTE:
  736.       /* This value is stored in network byte order, no need to switch
  737.        * it back
  738.        */
  739.       *(SSMPRUint32 *)curptr = value->u.string->m_length;
  740.       curptr = (SSMPRInt32 *)curptr + 1;
  741.       memcpy(curptr, &value->u.string->m_data, 
  742.              PR_ntohl(value->u.string->m_length));
  743.       break;
  744.    case SSM_RID_ATTRIBUTE:
  745.       *(SSMPRUint32 *)curptr = SSMPR_htonl(value->u.rid);
  746.       break;
  747.    case SSM_NUMERIC_ATTRIBUTE:
  748.       *(SSMPRUint32 *)curptr = SSMPR_htonl(value->u.numeric);
  749.       break;
  750.   }
  751.   
  752.   return blobSize;
  753. }
  754. SSMPRStatus
  755. SSM_ParseSetAttribRequest(SECItem             *msg,
  756.   SSMPRInt32          *resourceID,
  757.   SSMPRInt32          *fieldID,
  758.   SSMAttributeValue   *value)
  759. {
  760.   unsigned char *curPtr;
  761.   SSMPRInt32 strLen;
  762.   if (!msg      || !msg->data || !resourceID || !fieldID || !value){
  763.     SSMPORT_SetError(SSMPR_INVALID_ARGUMENT_ERROR);
  764.     return SSMPR_FAILURE;
  765.   }
  766.   curPtr = msg->data;
  767.   value->type = msg->type & SSM_SPECIFIC_MASK;
  768.   switch (value->type) {
  769.   case SSM_NUMERIC_ATTRIBUTE:
  770.     *resourceID = SSMPR_ntohl(*(SSMPRInt32*)curPtr);
  771.     curPtr += sizeof(SSMPRInt32);
  772.     *fieldID = SSMPR_ntohl(*(SSMPRInt32*)curPtr);
  773.     curPtr += sizeof(SSMPRInt32);
  774.     value->u.numeric = SSMPR_ntohl(*(SSMPRInt32*)curPtr);
  775.     break;
  776.   case SSM_RID_ATTRIBUTE:
  777.     *resourceID = SSMPR_ntohl(*(SSMPRInt32*)curPtr);
  778.     curPtr += sizeof(SSMPRInt32);
  779.     *fieldID = SSMPR_ntohl(*(SSMPRInt32*)curPtr);
  780.     curPtr += sizeof(SSMPRInt32);
  781.     value->u.rid = SSMPR_ntohl(*(SSMPRInt32*)curPtr);
  782.     break;
  783.   case SSM_STRING_ATTRIBUTE:
  784.     *resourceID = SSMPR_ntohl(*(SSMPRInt32*)curPtr);
  785.     curPtr += sizeof(SSMPRInt32);
  786.     *fieldID = SSMPR_ntohl(*(SSMPRInt32*)curPtr);
  787.     curPtr += sizeof(SSMPRInt32);
  788.     strLen = msg->len - (curPtr - msg->data);
  789.     value->u.string = SSMPORT_ZAlloc(strLen);
  790.     memcpy (value->u.string, curPtr, strLen);
  791.     break;
  792.   default:
  793.     return SSMPR_FAILURE;
  794.   }
  795.   
  796.   return SSMPR_SUCCESS;
  797. }
  798. /* Messages to pickle and unpickle a resource. */
  799. SSMPRStatus SSM_ParsePickleResourceRequest(void * pickleResourceRequest, 
  800.   SSMPRUint32 * resourceID)
  801.   void * curptr = pickleResourceRequest;
  802.   PRStatus rv = PR_SUCCESS;
  803.   if (!pickleResourceRequest) { 
  804.     rv = PR_INVALID_ARGUMENT_ERROR;
  805.     goto loser;
  806.   }
  807.   if (resourceID) *resourceID = SSMPR_ntohl(*(SSMPRUint32 *)curptr);
  808.   
  809. loser:
  810.   if (pickleResourceRequest)
  811.      SSMPORT_Free(pickleResourceRequest);
  812.   return rv;
  813. }
  814. SSMPRInt32 SSM_PackPickleResourceReply(void ** pickleResourceReply, 
  815.        SSMPRInt32 result,
  816.        SSMPRUint32 resourceLen, 
  817.        void * resource)
  818.     SSMPRInt32 blobSize;
  819.     void * curptr, *tmpStr = NULL;
  820.     PRStatus rv;
  821.     
  822.     if (!pickleResourceReply) 
  823.       goto loser;
  824.     
  825.     *pickleResourceReply = NULL;
  826.     blobSize = sizeof(SSMPRInt32) + sizeof(SSMPRUint32) + 
  827. SSMSTRING_PADDED_LENGTH(resourceLen); 
  828.     
  829.     /* allocate space for the helloRequest "blob" */
  830.     curptr = (void *)SSMPORT_ZAlloc(blobSize);
  831.     if (!curptr)  
  832.       goto loser;
  833.     
  834.     *pickleResourceReply = curptr;
  835.     *(SSMPRInt32 *)curptr = SSMPR_htonl(result);
  836.     curptr = (SSMPRInt32 *)curptr + 1;
  837.     
  838.     rv = SSM_StringToSSMString((SSMString **)&tmpStr, resourceLen, resource);
  839.     if (rv != SSMPR_SUCCESS) 
  840.       goto loser;
  841.     memcpy(curptr, tmpStr, SSM_SIZEOF_STRING(*(SSMString *)tmpStr));
  842.     goto done;
  843. loser:
  844.     if (pickleResourceReply && *pickleResourceReply) 
  845.       PR_Free(*pickleResourceReply);
  846.     if (tmpStr) 
  847.       PR_Free(tmpStr);
  848. done:
  849.     return blobSize;
  850. }
  851. SSMPRStatus SSM_ParseUnpickleResourceRequest(void * unpickleResourceRequest, 
  852.      SSMPRUint32 blobSize,
  853.      SSMPRUint32 * resourceType,
  854.      SSMPRUint32 * resourceLen, 
  855.      void ** resource)
  856. {
  857.     void * curptr = unpickleResourceRequest;
  858.     SSMPRStatus rv = PR_SUCCESS;
  859.     
  860.     if (!unpickleResourceRequest) { 
  861.         rv = PR_INVALID_ARGUMENT_ERROR;
  862.         goto loser;
  863.     }
  864.     if (resourceType)  
  865.         *resourceType = PR_ntohl(*(SSMPRUint32 *)curptr);
  866.     curptr = (SSMPRUint32 *)curptr + 1;
  867.     
  868.     if (resource) {
  869.         rv = SSM_SSMStringToString((char **)resource,  (SSMPRInt32 *)resourceLen, 
  870.                                    (SSMString *)curptr);
  871.         if (rv != SSMPR_SUCCESS)  
  872.             goto loser; 
  873.     }
  874.     goto done;
  875. loser:
  876.     if (resource && *resource)
  877.       PR_Free(*resource);
  878. done: 
  879.     if (unpickleResourceRequest)
  880.       PR_Free(unpickleResourceRequest); 
  881.     return rv;
  882. }
  883. SSMPRInt32 SSM_PackUnpickleResourceReply(void ** unpickleResourceReply, 
  884.  SSMPRInt32 result, 
  885.  SSMPRUint32 resourceID)
  886. {
  887.   SSMPRInt32 blobSize;
  888.   void * curptr;
  889.   
  890.   if (!unpickleResourceReply) {
  891.     SSMPORT_SetError(SSMPR_INVALID_ARGUMENT_ERROR);
  892.     return 0;
  893.   }  
  894.   *unpickleResourceReply = NULL;
  895.   blobSize = sizeof(SSMPRInt32) + sizeof(SSMPRUint32);
  896.   /* allocate space for the helloRequest "blob" */
  897.   curptr = (void *)SSMPORT_ZAlloc(blobSize);
  898.   if (!curptr) { 
  899.     SSMPORT_SetError(SSMPR_OUT_OF_MEMORY_ERROR);
  900.     return 0;
  901.   }
  902.   *unpickleResourceReply = curptr;
  903.   *(SSMPRInt32 *)curptr = SSMPR_htonl(result);
  904.   curptr = (SSMPRInt32 *)curptr + 1;
  905.   *(SSMPRUint32 *)curptr = SSMPR_htonl(resourceID);
  906.   return blobSize;
  907. }
  908. /* Destroy resource messages */
  909. SSMPRStatus SSM_ParseDestroyResourceRequest(void * destroyResourceRequest, 
  910.     SSMPRUint32 * resourceID, 
  911.     SSMPRUint32 * resourceType)
  912.   void * curptr = destroyResourceRequest;
  913.   PRStatus rv = PR_SUCCESS;
  914.   if (!destroyResourceRequest) { 
  915.     rv = PR_INVALID_ARGUMENT_ERROR;
  916.     goto loser;
  917.   }
  918.   if (resourceID) *resourceID = SSMPR_ntohl(*(SSMPRUint32 *)curptr);
  919.   curptr = (SSMPRUint32 *)curptr + 1;
  920.   if (resourceType) *resourceType = SSMPR_ntohl(*(SSMPRUint32 *)curptr);
  921. loser:
  922.   if (destroyResourceRequest)
  923.      SSMPORT_Free(destroyResourceRequest);
  924.   return rv;
  925. }
  926.  
  927. SSMPRInt32 SSM_PackDestroyResourceReply(void ** destroyResourceReply, 
  928. SSMPRInt32 result)
  929. {
  930.     return SSM_PackSingleNumReply(destroyResourceReply, result);
  931. }
  932. SSMPRStatus SSM_ParseVerifyCertRequest(void * verifyCertRequest, 
  933.                                        SSMPRUint32 * resourceID, 
  934.                                        SSMPRInt32 * certUsage)
  935. {
  936.   void * curptr = verifyCertRequest;
  937.   PRStatus rv = PR_SUCCESS;
  938.   if (!verifyCertRequest) { 
  939.     rv = PR_INVALID_ARGUMENT_ERROR;
  940.     goto loser;
  941.   }
  942.   if (resourceID) *resourceID = SSMPR_ntohl(*(SSMPRUint32 *)curptr);
  943.   curptr = (SSMPRUint32 *)curptr + 1;
  944.   if (certUsage) *certUsage = SSMPR_ntohl(*(SSMPRInt32 *)curptr);
  945. loser:
  946.   if (verifyCertRequest)
  947.   SSMPORT_Free(verifyCertRequest);
  948.   return rv;
  949. }
  950. SSMPRInt32 SSM_PackVerifyCertReply(void ** verifyCertReply, 
  951.                                    SSMPRInt32 result)
  952. {
  953.   SSMPRInt32 blobSize;
  954.   void * curptr;
  955.   
  956.   if (!verifyCertReply) {
  957.     SSMPORT_SetError(SSMPR_INVALID_ARGUMENT_ERROR);
  958.     return 0;
  959.   }
  960.   *verifyCertReply = NULL;
  961.   blobSize = sizeof(SSMPRInt32);
  962.   /* allocate space for the helloRequest "blob" */
  963.   curptr = (void *)SSMPORT_ZAlloc(blobSize);
  964.   if (!curptr) { 
  965.     SSMPORT_SetError(SSMPR_OUT_OF_MEMORY_ERROR);
  966.     return 0;
  967.   }
  968.   *verifyCertReply = curptr;
  969.   *(SSMPRInt32 *)curptr = SSMPR_htonl(result);
  970.   
  971.   return blobSize;
  972. }
  973. SSMPRStatus 
  974. SSM_ParseImportCertRequest(void * importCertRequest, 
  975.    SSMPRUint32 * blobLen, 
  976.    void ** certBlob)
  977. {
  978.   PRStatus rv;
  979.   void * curptr = importCertRequest;
  980.   PRUint32 length = 0;
  981.   if (!importCertRequest) {
  982.      rv = PR_INVALID_ARGUMENT_ERROR;
  983.      goto loser;
  984.   }
  985.   
  986.   /* in case we fail */
  987.   if (certBlob) *certBlob = NULL; 
  988.   if (blobLen) 
  989.     *blobLen = 0;
  990.   if (certBlob) {
  991.     rv = SSM_SSMStringToString((char **)certBlob,  (SSMPRInt32 *)&length, 
  992.        (SSMString *)curptr);
  993.     if (rv != SSMPR_SUCCESS)  
  994.        goto loser;   
  995.   } 
  996.   if (blobLen) 
  997.     *blobLen = length;
  998.   goto done;
  999. loser:
  1000.    if (certBlob && *certBlob)
  1001. PR_Free(*certBlob);
  1002. done:
  1003.    if (importCertRequest)
  1004.       SSMPORT_Free(importCertRequest);
  1005.    return rv;
  1006. }
  1007.   
  1008. SSMPRInt32 
  1009. SSM_PackImportCertReply(void ** importCertReply, SSMPRInt32 result, 
  1010. SSMPRUint32 resourceID)
  1011.   {
  1012.     SSMPRInt32 blobSize;
  1013.     void * curptr;
  1014.     
  1015.     if (!importCertReply) 
  1016.       goto loser;
  1017.     
  1018.     *importCertReply = NULL;
  1019.     blobSize = sizeof(SSMPRInt32) + sizeof(SSMPRUint32);
  1020.     
  1021.     /* allocate space for the "blob" */
  1022.     curptr = (void *)SSMPORT_ZAlloc(blobSize);
  1023.     if (!curptr) 
  1024.       goto loser;
  1025.     *importCertReply = curptr;
  1026.     *(SSMPRInt32 *)curptr = SSMPR_htonl(result);
  1027.     curptr = (SSMPRInt32 *)curptr + 1;
  1028.     *(SSMPRUint32 *)curptr = SSMPR_htonl(resourceID);
  1029.     
  1030.     return blobSize;
  1031.   loser:
  1032.     if (importCertReply && *importCertReply)
  1033.       PR_Free(*importCertReply);
  1034.     return 0;
  1035.   }
  1036. PRStatus
  1037. SSM_ParseFindCertByNicknameRequest(void *request, char ** nickname)
  1038. {
  1039.     unsigned char * curPtr = request;
  1040.     PRStatus rv = PR_SUCCESS;
  1041.     /* Do some basic parameter checking */
  1042.     if (!request || !nickname) {
  1043.         rv = PR_FAILURE;
  1044.         goto loser;
  1045.     }
  1046.     /* Get the certificate nickname */
  1047.     rv = SSM_SSMStringToString(nickname, NULL, (SSMString*)curPtr);
  1048.     if (rv != PR_SUCCESS) {
  1049.         goto loser;
  1050.     }
  1051.     goto done;
  1052. loser:
  1053. done:
  1054.     if (request) {
  1055.         PR_Free(request);
  1056.     }
  1057.     return rv;
  1058. }
  1059. PRInt32
  1060. SSM_PackFindCertByNicknameReply(void ** reply, PRUint32 resourceID)
  1061. {
  1062.     unsigned char *curPtr;
  1063.     PRInt32 replyLength;
  1064.     /* Do some basic parameter checking */
  1065.     if (!reply) {
  1066.         goto loser;
  1067.     }
  1068.     /* Calculate the message length */
  1069.     replyLength = sizeof(PRUint32);
  1070.     curPtr = *reply = PR_Malloc(replyLength);
  1071.     if (!curPtr) {
  1072.         goto loser;
  1073.     }
  1074.     *(PRUint32*)curPtr = PR_htonl(resourceID);
  1075.     return replyLength;
  1076. loser:
  1077.     if (reply && *reply) {
  1078.         PR_Free(*reply);
  1079.     }
  1080.     return 0;
  1081. }
  1082. PRStatus
  1083. SSM_ParseFindCertByKeyRequest(void *request, SECItem ** key)
  1084. {
  1085.     unsigned char *curPtr = request;
  1086.     PRStatus rv = PR_SUCCESS;
  1087.     /* Do some basic parameter checking */
  1088.     if (!request || !key) {
  1089.         rv = PR_FAILURE;
  1090.         goto loser;
  1091.     }
  1092.     /* Allocate the key */
  1093.     *key = PR_NEWZAP(SECItem);
  1094.     if (!(*key)) {
  1095.         goto loser;
  1096.     }
  1097.     /* Get the key */
  1098.     rv = SSM_SSMStringToString(&((*key)->data), &((*key)->len),
  1099.        (SSMString*)curPtr);
  1100.     if (rv != PR_SUCCESS) {
  1101.         goto loser;
  1102.     }
  1103.     goto done;
  1104. loser:
  1105.     if (*key) {
  1106.         if ((*key)->data) {
  1107.             PR_Free((*key)->data);
  1108.         }
  1109.         PR_Free(*key);
  1110.     }
  1111. done:
  1112.     if (request) {
  1113.         PR_Free(request);
  1114.     }
  1115.     return rv;
  1116. }
  1117. PRInt32
  1118. SSM_PackFindCertByKeyReply(void ** reply, PRUint32 resourceID)
  1119. {
  1120.     unsigned char *curPtr;
  1121.     PRInt32 replyLength;
  1122.     /* Do some basic parameter checking */
  1123.     if (!reply) {
  1124.         goto loser;
  1125.     }
  1126.     /* Calculate the message length */
  1127.     replyLength = sizeof(PRUint32);
  1128.     curPtr = *reply = PR_Malloc(replyLength);
  1129.     if (!curPtr) {
  1130.         goto loser;
  1131.     }
  1132.     *(PRUint32*)curPtr = PR_htonl(resourceID);
  1133.     return replyLength;
  1134. loser:
  1135.     if (reply && *reply) {
  1136.         PR_Free(*reply);
  1137.     }
  1138.     return 0;
  1139. }
  1140. PRStatus
  1141. SSM_ParseFindCertByEmailAddrRequest(void *request, char ** emailAddr)
  1142. {
  1143.     unsigned char * curPtr = request;
  1144.     PRStatus rv = PR_SUCCESS;
  1145.     /* Do some basic parameter checking */
  1146.     if (!request || !emailAddr) {
  1147.         rv = PR_FAILURE;
  1148.         goto loser;
  1149.     }
  1150.     /* Get the certificate nickname */
  1151.     rv = SSM_SSMStringToString(emailAddr, NULL, (SSMString*)curPtr);
  1152.     if (rv != PR_SUCCESS) {
  1153.         goto loser;
  1154.     }
  1155.     goto done;
  1156. loser:
  1157. done:
  1158.     if (request) {
  1159.         PR_Free(request);
  1160.     }
  1161.     return rv;
  1162. }
  1163. PRInt32
  1164. SSM_PackFindCertByEmailAddrReply(void ** reply, PRUint32 resourceID)
  1165. {
  1166.     unsigned char *curPtr;
  1167.     PRInt32 replyLength;
  1168.     /* Do some basic parameter checking */
  1169.     if (!reply) {
  1170.         goto loser;
  1171.     }
  1172.     /* Calculate the message length */
  1173.     replyLength = sizeof(PRUint32);
  1174.     curPtr = *reply = PR_Malloc(replyLength);
  1175.     if (!curPtr) {
  1176.         goto loser;
  1177.     }
  1178.     *(PRUint32*)curPtr = PR_htonl(resourceID);
  1179.     return replyLength;
  1180. loser:
  1181.     if (reply && *reply) {
  1182.         PR_Free(*reply);
  1183.     }
  1184.     return 0;
  1185. }
  1186. PRStatus
  1187. SSM_ParseAddTempCertToDBRequest(void *request, PRUint32 *resourceID, char ** nickname, PRInt32 *ssl, PRInt32 *email, PRInt32 *objectSigning)
  1188. {
  1189.     unsigned char * curPtr = request;
  1190.     PRStatus rv = PR_SUCCESS;
  1191.     /* Do some basic parameter checking */
  1192.     if (!request || !resourceID || !nickname) {
  1193.         rv = PR_FAILURE;
  1194.         goto loser;
  1195.     }
  1196.     /* Get the resource ID */
  1197.     *resourceID = PR_ntohl(*(PRInt32*)curPtr);
  1198.     curPtr += sizeof(PRInt32);
  1199.     /* Get the nickname */
  1200.     rv = SSM_SSMStringToString(nickname, NULL, (SSMString*)curPtr);
  1201.     if (rv != PR_SUCCESS) {
  1202.         goto loser;
  1203.     }
  1204.     /* SSL */
  1205.     *ssl = PR_ntohl(*(PRInt32*)curPtr);
  1206.     curPtr += sizeof(PRInt32);
  1207.     /* Email */
  1208.     *email = PR_ntohl(*(PRInt32*)curPtr);
  1209.     curPtr += sizeof(PRInt32);
  1210.     /* Object signing */
  1211.     *objectSigning = PR_ntohl(*(PRInt32*)curPtr);
  1212.     curPtr += sizeof(PRInt32);
  1213.     goto done;
  1214. loser:
  1215.     if (nickname && *nickname) {
  1216.         PR_Free(*nickname);
  1217.     }
  1218. done:
  1219.     if (request) {
  1220.         PR_Free(request);
  1221.     }
  1222.     return rv;
  1223. }
  1224. PRInt32
  1225. SSM_PackAddTempCertToDBReply(void ** reply)
  1226. {
  1227.     unsigned char *curPtr;
  1228.     PRInt32 replyLength;
  1229.     /* Do some basic parameter checking */
  1230.     if (!reply) {
  1231.         goto loser;
  1232.     }
  1233.     /* Calculate the message length */
  1234.     replyLength = sizeof(PRInt32)*3;
  1235.     curPtr = *reply = PR_Malloc(replyLength);
  1236.     if (!curPtr) {
  1237.         goto loser;
  1238.     }
  1239.     return replyLength;
  1240. loser:
  1241.     if (reply && *reply) {
  1242.         PR_Free(*reply);
  1243.     }
  1244.     return 0;
  1245. }
  1246. PRStatus SSM_ParseMatchUserCertRequest(void *request, MatchUserCertRequestData** data)
  1247. {
  1248.     MatchUserCertRequestData * requestData;
  1249.     char *curPtr = request;
  1250.     PRStatus rv = PR_SUCCESS;
  1251.     int i;
  1252.     /* Do some basic parameter checking */
  1253.     if (!request || !data) {
  1254.         rv = PR_FAILURE;
  1255.         goto loser;
  1256.     }
  1257.     /* Allocate the reply structure */
  1258.     requestData = PR_NEWZAP(MatchUserCertRequestData);
  1259.     if (NULL == requestData) {
  1260.         rv = PR_FAILURE;
  1261.         goto loser;
  1262.     }
  1263.     /* Get the cert type */
  1264.     requestData->certType = PR_ntohl(*(PRUint32*)curPtr);
  1265.     curPtr += sizeof(PRUint32);
  1266.     /* Get the number of CAs */
  1267.     requestData->numCANames = PR_ntohl(*(PRInt32*)curPtr);
  1268.     curPtr += sizeof(PRInt32);
  1269.     /* Get the CA names */
  1270.     for (i = 0; i < requestData->numCANames; i++) {
  1271.         rv = SSM_SSMStringToString(&(requestData->caNames[i]), NULL, (SSMString*)curPtr);
  1272.         if (rv != PR_SUCCESS) {
  1273.             goto loser;
  1274.         }
  1275.         curPtr += SSM_SIZEOF_STRING(*(SSMString*)curPtr);
  1276.     }
  1277.     *data = requestData;
  1278.     goto done;
  1279. loser:
  1280.     if (requestData) {
  1281.         PR_Free(requestData);
  1282.     }
  1283. done:
  1284.     if (request) {
  1285.         PR_Free(request);
  1286.     }
  1287.     return rv;
  1288. }
  1289. PRInt32 SSM_PackMatchUserCertReply(void **reply, SSMCertList * certList)
  1290. {
  1291.     unsigned char *curPtr;
  1292.     PRInt32 replyLength;
  1293.     int i;
  1294.     SSMCertListElement *head;
  1295.     /* Do some basic parameter checking */
  1296.     if (!reply) {
  1297.         goto loser;
  1298.     }
  1299.     /* Calculate the message length */
  1300.     replyLength = sizeof(PRInt32) + (certList->count)*sizeof(PRUint32);
  1301.     curPtr = *reply = PR_Malloc(replyLength);
  1302.     if (!curPtr) {
  1303.         goto loser;
  1304.     }
  1305.     /* Count */
  1306.     *((PRInt32*)curPtr) = PR_htonl(certList->count);
  1307.     curPtr += sizeof(PRInt32);
  1308.     /* Get the first element */
  1309.     head = SSM_CERT_LIST_ELEMENT_PTR(certList->certs.next);
  1310.     for (i = 0; i < certList->count; i++) {
  1311.         *((PRUint32*)curPtr) = PR_htonl(head->certResID);
  1312.         curPtr += sizeof(PRUint32);
  1313.         head = SSM_CERT_LIST_ELEMENT_PTR(head->links.next);
  1314.     }
  1315.     return replyLength;
  1316. loser:
  1317.     /* XXX Free memory here */
  1318.     return 0;
  1319. }
  1320. SSMPRInt32
  1321. SSM_PackErrorMessage(void ** errorReply, SSMPRInt32 result)
  1322. {
  1323.   SSMPRInt32 blobSize;
  1324.   
  1325.   if (!errorReply) {
  1326.     SSMPORT_SetError(SSMPR_INVALID_ARGUMENT_ERROR);
  1327.     return 0;
  1328.   }  
  1329.   *errorReply = NULL;
  1330.   blobSize = sizeof(SSMPRInt32) + sizeof(SSMPRUint32);
  1331.   /* allocate space for the "blob" */
  1332.   *errorReply = (void *)SSMPORT_ZAlloc(blobSize);
  1333.   if (!*errorReply) { 
  1334.     SSMPORT_SetError(SSMPR_OUT_OF_MEMORY_ERROR);
  1335.     return 0;
  1336.   }
  1337.   *(SSMPRInt32 *)(*errorReply) = SSMPR_htonl(result);
  1338.   return blobSize;
  1339. }
  1340. SSMPRStatus
  1341. SSM_ParseKeyPairGenRequest(void *keyPairGenRequest, SSMPRInt32 requestLen,
  1342.                            SSMPRUint32 *keyGenCtxtID,
  1343.    SSMPRUint32 *genMechanism,  
  1344.    SSMPRUint32 *keySize, unsigned char **params,
  1345.    SSMPRUint32 *paramLen)
  1346. {
  1347.   unsigned char *curPtr = (unsigned char*)keyPairGenRequest;
  1348.   SSMPRStatus    rv     = SSMPR_SUCCESS;
  1349.   if (!keyPairGenRequest) {
  1350.     SSMPORT_SetError(SSMPR_INVALID_ARGUMENT_ERROR);
  1351.     return SSMPR_FAILURE;
  1352.   }
  1353.   /* Now fetch all of the stuff out */
  1354.   if (keyGenCtxtID)
  1355.     *keyGenCtxtID =SSMPR_ntohl(*((SSMPRInt32*)curPtr));
  1356.   curPtr += sizeof(SSMPRInt32);
  1357.   if (genMechanism)
  1358.     *genMechanism =SSMPR_ntohl(*((SSMPRInt32*)curPtr));
  1359.   curPtr += sizeof(SSMPRInt32);
  1360.   if (keySize)
  1361.     *keySize = SSMPR_ntohl(*((SSMPRInt32*)curPtr));
  1362.   curPtr += sizeof(SSMPRInt32);
  1363.   rv = SSM_SSMStringToString((char**)params, (int*)paramLen, 
  1364.      (SSMString*)curPtr);
  1365.   return rv;
  1366. }
  1367. SSMPRInt32
  1368. SSM_PackKeyPairGenResponse(void ** keyPairGenResponse, SSMPRUint32 keyPairId)
  1369. {
  1370.   SSMPRInt32     blobSize;
  1371.   unsigned char *curPtr;
  1372.   blobSize = sizeof (SSMPRInt32);
  1373.   *keyPairGenResponse = curPtr = PORT_ZAlloc(blobSize);
  1374.   if (curPtr == NULL) {
  1375.       SSMPORT_SetError(SSMPR_OUT_OF_MEMORY_ERROR);
  1376.       return 0;
  1377.   }
  1378.   *((SSMPRInt32*)curPtr) = SSMPR_htonl(keyPairId);
  1379.   return blobSize;
  1380. }
  1381. PRStatus
  1382. SSM_ParseFinishKeyGenRequest(void    *finishKeyGenRequest,
  1383.                              PRInt32  requestLen,
  1384.                              PRInt32 *keyGenContext)
  1385. {
  1386.   if (!finishKeyGenRequest || !keyGenContext) {
  1387.     SSMPORT_SetError(SSMPR_INVALID_ARGUMENT_ERROR);
  1388.     return PR_FAILURE;
  1389.   }
  1390.   *keyGenContext = PR_ntohl(*((PRInt32*)finishKeyGenRequest));
  1391.   PR_ASSERT(requestLen == sizeof(PRInt32));
  1392.   return PR_SUCCESS;
  1393. }
  1394. SSMPRStatus 
  1395. SSM_ParseCreateCRMFReqRequest(void        *crmfReqRequest,
  1396.       SSMPRInt32   requestLen,
  1397.       SSMPRUint32 *keyPairId)
  1398. {
  1399.   if (!crmfReqRequest || !keyPairId) {
  1400.     SSMPORT_SetError(SSMPR_INVALID_ARGUMENT_ERROR);
  1401.     return SSMPR_FAILURE;
  1402.   }
  1403.   *keyPairId = SSMPR_ntohl(*((SSMPRInt32*)crmfReqRequest));
  1404.   return SSMPR_SUCCESS;
  1405. }
  1406. SSMPRInt32
  1407. SSM_PackCreateCRMFReqReply(void        **crmfReqReply,
  1408.    SSMPRUint32   crmfReqId)
  1409. {
  1410.   SSMPRInt32 blobSize;
  1411.   unsigned char *curPtr;
  1412.   blobSize = sizeof(SSMPRInt32);
  1413.   *crmfReqReply = curPtr = (unsigned char *) PORT_ZAlloc(blobSize);
  1414.   *((SSMPRInt32*)curPtr) = SSMPR_htonl(crmfReqId);
  1415.   return blobSize;
  1416. }
  1417. SSMPRStatus
  1418. SSM_ParseEncodeCRMFReqRequest(void         *encodeReq,
  1419.       SSMPRInt32    requestLen,
  1420.       SSMPRUint32 **crmfReqIds,
  1421.       SSMPRInt32   *numRequests)
  1422. {
  1423.   unsigned char *curPtr = (unsigned char*)encodeReq;
  1424.   SSMPRInt32 i;
  1425.   SSMPRUint32 *reqIdArr;
  1426.   if (!encodeReq || !crmfReqIds || !numRequests) {
  1427.     SSMPORT_SetError(SSMPR_INVALID_ARGUMENT_ERROR);
  1428.     return SSMPR_FAILURE;
  1429.   }
  1430.   *numRequests = SSMPR_ntohl(*((SSMPRInt32*)encodeReq));
  1431.   curPtr += sizeof(SSMPRInt32);
  1432.   *crmfReqIds = reqIdArr = SSMPORT_ZNewArray(SSMPRUint32, *numRequests);
  1433.   if (reqIdArr == NULL) {
  1434.     return SSMPR_FAILURE;
  1435.   }
  1436.   for (i=0; i<*numRequests;i++) {
  1437.     reqIdArr[i] = SSMPR_ntohl(*((SSMPRUint32*)curPtr));
  1438.     curPtr += sizeof(SSMPRUint32);
  1439.   } 
  1440.   return SSMPR_SUCCESS;
  1441. }
  1442. SSMPRInt32
  1443. SSM_PackEncodeCRMFReqReply(void        **encodeReply,
  1444.    char         *crmfDER,
  1445.    SSMPRUint32   derLen)
  1446. {
  1447.   char       *reply;
  1448.   SSMPRInt32  blobSize;
  1449.   blobSize = SSMSTRING_PADDED_LENGTH(derLen)+sizeof(SSMPRUint32);
  1450.   *encodeReply = reply = (char *) PORT_ZAlloc(blobSize);
  1451.   *((SSMPRUint32*)reply) = SSMPR_ntohl(derLen);
  1452.   reply += sizeof (SSMPRUint32);
  1453.   memcpy(reply, crmfDER, derLen);
  1454.   reply += derLen;
  1455.   memset(reply, 0 , blobSize - (reply - (*(char**)encodeReply)));
  1456.   return blobSize;
  1457. }
  1458. SSMPRStatus
  1459. SSM_ParseCMMFCertResponse(void        *encodedRes,
  1460.   SSMPRInt32   encodeLen,
  1461.   char       **nickname,
  1462.   char       **base64Der,
  1463.   PRBool      *doBackup)
  1464. {
  1465.   SSMPRStatus  rv;
  1466.   char        *curPtr;
  1467.   if (encodedRes == NULL || nickname == NULL || 
  1468.       base64Der  == NULL || doBackup == NULL) {
  1469.       return SSMPR_FAILURE;
  1470.   }
  1471.   curPtr = encodedRes;
  1472.   PR_ASSERT(*nickname == NULL && *base64Der == NULL);
  1473.   *nickname = *base64Der = NULL;
  1474.   rv = SSM_SSMStringToString(nickname, NULL, (SSMString*)curPtr);
  1475.   if (rv != SSMPR_SUCCESS) {
  1476.       goto loser;
  1477.   }
  1478.   curPtr += SSM_SIZEOF_STRING(*(SSMString*)curPtr);
  1479.   rv = SSM_SSMStringToString(base64Der, NULL, (SSMString*)curPtr);
  1480.   if (rv != SSMPR_SUCCESS) {
  1481.       goto loser;
  1482.   }
  1483.   curPtr += SSM_SIZEOF_STRING(*(SSMString*)curPtr);
  1484.   *doBackup = (SSMPR_ntohl(*(SSMPRUint32*)curPtr) == 0) ? PR_FALSE : PR_TRUE;
  1485.   return SSMPR_SUCCESS;
  1486.  loser:
  1487.   if (nickname && *nickname) {
  1488.       PR_Free(*nickname);
  1489.   }
  1490.   if (base64Der && *base64Der) {
  1491.       PR_Free(*base64Der);
  1492.   }
  1493.   return SSMPR_FAILURE;
  1494. }
  1495. PRStatus SSM_ParsePOPChallengeRequest(void     *challenge,
  1496.       PRInt32   len,
  1497.       char    **responseString)
  1498. {
  1499.   if (challenge == NULL || responseString == NULL) {
  1500.     return PR_FAILURE;
  1501.   }
  1502.   *responseString = NULL;
  1503.   return  SSM_SSMStringToString(responseString, NULL, (SSMString*)challenge);
  1504.     
  1505. }
  1506. PRInt32 SSM_PackPOPChallengeResponse(void   **response,
  1507.      char    *responseString,
  1508.      PRInt32  responseStringLen)
  1509. {
  1510.   PRInt32  blobSize;
  1511.   blobSize = SSMSTRING_PADDED_LENGTH(responseStringLen)+sizeof(PRInt32);
  1512.   *response = SSMPORT_ZNewArray(char, blobSize);
  1513.   if (SSM_StringToSSMString((SSMString**)response, responseStringLen,
  1514.     responseString) != PR_SUCCESS) {
  1515.     return 0;
  1516.   }
  1517.   return blobSize;
  1518. }
  1519. PRInt32 SSM_PackPasswdRequest(void ** passwdRequest, PRInt32 tokenID, 
  1520.       char * prompt, PRInt32 promptLen)
  1521. {
  1522.   void * curptr, * tmpStr = NULL;
  1523.   PRInt32 blobSize;
  1524.   PRStatus rv = PR_SUCCESS;
  1525.   if (!passwdRequest || !prompt || tokenID == 0 || promptLen == 0)
  1526.     {
  1527.       SSMPORT_SetError(SSMPR_INVALID_ARGUMENT_ERROR);
  1528.       goto loser;
  1529.     }
  1530.   *passwdRequest = NULL; /* in case we fail */
  1531.   blobSize = sizeof(PRInt32)*2 + SSMSTRING_PADDED_LENGTH(promptLen);
  1532.   curptr = *passwdRequest = PORT_ZAlloc(blobSize);
  1533.   if (!*passwdRequest) {
  1534.     SSMPORT_SetError(SSMPR_OUT_OF_MEMORY_ERROR);
  1535.     goto loser;
  1536.   }
  1537.     
  1538.   *(PRInt32 *)curptr = PR_htonl(tokenID);
  1539.   curptr = (PRInt32 *)curptr + 1;
  1540.   
  1541.   rv = SSM_StringToSSMString((SSMString **)&tmpStr, promptLen, prompt);
  1542.   if (rv != PR_SUCCESS) 
  1543.     goto loser;
  1544.   memcpy(curptr, tmpStr, SSM_SIZEOF_STRING(*(SSMString *)tmpStr));
  1545.   goto done;
  1546. loser:
  1547.   if (passwdRequest && *passwdRequest) 
  1548.     PR_Free(passwdRequest);
  1549. done:
  1550.   if (tmpStr) 
  1551.     PR_Free(tmpStr);
  1552.   return blobSize;
  1553. }
  1554. PRStatus SSM_ParsePasswordReply(void * passwdReply, PRInt32 * result, 
  1555.                                 PRInt32 * tokenID,
  1556. char ** passwd, PRInt32 * passwdLen)
  1557. {
  1558.   PRStatus rv = PR_SUCCESS;
  1559.   void * curptr = passwdReply; 
  1560.   
  1561.   if (!passwdReply) { 
  1562.     rv = PR_INVALID_ARGUMENT_ERROR;
  1563.     goto loser;
  1564.   }
  1565.  
  1566.   if (result) 
  1567.     *result = PR_ntohl(*(PRInt32 *)curptr);
  1568.   curptr = (PRInt32 *)curptr + 1;
  1569.    
  1570.   if (tokenID) 
  1571.     *tokenID = PR_ntohl(*(PRInt32 *)curptr);
  1572.   curptr = (PRInt32 *)curptr + 1;
  1573.   
  1574.   if (passwd) {
  1575.     *passwd = NULL;
  1576.     rv = SSM_SSMStringToString(passwd, passwdLen, (SSMString *)curptr);
  1577.     if (rv != PR_SUCCESS && *passwd) {
  1578.       PR_Free(*passwd);
  1579.       *passwd = NULL;
  1580.       passwdLen = 0;
  1581.       goto loser;
  1582.     }
  1583.   }
  1584.   goto done;
  1585. loser:
  1586.   if (rv == PR_SUCCESS) 
  1587.     rv = PR_FAILURE;
  1588.   if (passwd && *passwd) {
  1589.     PR_Free(*passwd);
  1590.     *passwd = NULL;
  1591.   }
  1592.   if (tokenID) 
  1593.     *tokenID = 0;
  1594.   if (passwdLen)
  1595.     *passwdLen = 0;
  1596. done: 
  1597.   return rv;
  1598. }
  1599. void SSM_DestroyAttrValue(SSMAttributeValue *value, PRBool freeit)
  1600. {
  1601.   if (value->type == SSM_STRING_ATTRIBUTE)
  1602.     PR_Free(value->u.string);
  1603.   value->type = 0;
  1604.   if (freeit)
  1605.     PR_Free(value);
  1606. }
  1607. /* Sign Text functions */
  1608. PRStatus SSM_ParseSignTextRequest(void* signTextRequest, PRInt32 len, PRUint32* resID, signTextRequestData ** data)
  1609. {
  1610.     unsigned char *curPtr = (unsigned char*)signTextRequest;
  1611.     signTextRequestData *signTextData = NULL;
  1612.     PRStatus rv;
  1613.     int i;
  1614.     /* Do some basic parameter checking */
  1615.     if (!signTextRequest || !resID || !data) {
  1616.         goto loser;
  1617.     }
  1618.     /* Allocate the reply structure */
  1619.     signTextData = PR_NEWZAP(signTextRequestData);
  1620.     if (NULL == signTextData) {
  1621.         goto loser;
  1622.     }
  1623.     /* Resource ID */
  1624.     *resID = PR_ntohl(*(PRInt32*)curPtr);
  1625.     curPtr += sizeof(PRInt32);
  1626.     /* String to sign */
  1627.     rv = SSM_SSMStringToString(&(signTextData->stringToSign), NULL, (SSMString*)curPtr);
  1628.     if (rv != PR_SUCCESS) {
  1629.         goto loser;
  1630.     }
  1631.     curPtr += SSM_SIZEOF_STRING(*(SSMString*)curPtr);
  1632.     /* Host name */
  1633.     rv = SSM_SSMStringToString(&(signTextData->hostName), NULL, (SSMString*)curPtr);
  1634.     if (rv != PR_SUCCESS) {
  1635.         goto loser;
  1636.     }
  1637.     curPtr += SSM_SIZEOF_STRING(*(SSMString*)curPtr);
  1638.     /* CA option */
  1639.     rv = SSM_SSMStringToString(&(signTextData->caOption), NULL, (SSMString*)curPtr);
  1640.     if (rv != PR_SUCCESS) {
  1641.         goto loser;
  1642.     }
  1643.     curPtr += SSM_SIZEOF_STRING(*(SSMString*)curPtr);
  1644.     /* Number of CAs */
  1645.     signTextData->numCAs = PR_ntohl(*(PRInt32*)curPtr);
  1646.     curPtr += sizeof(PRInt32);
  1647.     signTextData->caNames = PR_Malloc(sizeof(char*)*(signTextData->numCAs));
  1648.     for (i = 0; i < signTextData->numCAs; i++) {
  1649.         rv = SSM_SSMStringToString(&(signTextData->caNames[i]), NULL, (SSMString*)curPtr);
  1650.         if (rv != PR_SUCCESS) {
  1651.             goto loser;
  1652.         }
  1653.         curPtr += SSM_SIZEOF_STRING(*(SSMString*)curPtr);
  1654.     }
  1655.     *data = signTextData;
  1656.     /* Free the incoming data buffer */
  1657.     PR_Free(signTextRequest);
  1658.     
  1659.     return PR_SUCCESS;
  1660. loser:
  1661.     if (signTextData) {
  1662.         if (signTextData->stringToSign) {
  1663.             PR_Free(signTextData->stringToSign);
  1664.         }
  1665.         if (signTextData->hostName) {
  1666.             PR_Free(signTextData->hostName);
  1667.         }
  1668.         if (signTextData->numCAs) {
  1669.             /* XXX Free the CA Names */
  1670.         }
  1671.         PR_Free(signTextData);
  1672.     }
  1673.     return PR_FAILURE;
  1674. }
  1675. PRStatus SSM_ParseGetLocalizedTextRequest(void               *data,
  1676.                                           SSMLocalizedString *whichString)
  1677. {
  1678.     return SSM_ParseSingleNumRequest(data, (SSMPRUint32*)whichString);
  1679. PRInt32 SSM_PackGetLocalizedTextResponse(void               **data,
  1680.  SSMLocalizedString   whichString,
  1681.  char                *retString)
  1682. {
  1683.     char *tmpPtr;
  1684.     PRInt32 replyLen;
  1685.     int retStrLen;
  1686.     retStrLen = strlen(retString);
  1687.     replyLen = SSMSTRING_PADDED_LENGTH(retStrLen)+(2*sizeof(PRInt32));
  1688.     
  1689.     tmpPtr = SSMPORT_ZNewArray(char, replyLen);
  1690.     if (tmpPtr == NULL) {
  1691.       *data = NULL;
  1692.       return 0;
  1693.     }
  1694.     *data = tmpPtr;
  1695.     *(PRUint32*)tmpPtr = PR_htonl(whichString);
  1696.     tmpPtr += sizeof(PRUint32);
  1697.     *(PRUint32*)tmpPtr = PR_htonl(retStrLen);
  1698.     tmpPtr += sizeof(PRUint32);
  1699.     memcpy(tmpPtr, retString, retStrLen);
  1700.     return replyLen;
  1701. }
  1702. PRStatus SSM_ParseAddNewSecurityModuleRequest(void          *data, 
  1703.       char         **moduleName,
  1704.       char         **libraryPath, 
  1705.       unsigned long *pubMechFlags,
  1706.       unsigned long *pubCipherFlags)
  1707. {
  1708.     char *tmpPtr;
  1709.     PRStatus rv;
  1710.     if (data == NULL) {
  1711.        return PR_FAILURE;
  1712.     }
  1713.     if (moduleName != NULL) {
  1714.         *moduleName = NULL;
  1715.     }
  1716.     if (libraryPath != NULL) {
  1717.         *libraryPath = NULL;
  1718.     }
  1719.     tmpPtr = data;
  1720.     if (moduleName) {
  1721.       rv = SSM_SSMStringToString(moduleName, NULL, (SSMString*)tmpPtr);
  1722.       if (rv != PR_SUCCESS) {
  1723.   goto loser;
  1724.       }
  1725.     }
  1726.     tmpPtr += SSM_SIZEOF_STRING(*(SSMString*)tmpPtr);
  1727.     if (libraryPath) {
  1728.       rv =SSM_SSMStringToString(libraryPath, NULL, (SSMString*)tmpPtr);
  1729.       if (rv != PR_SUCCESS) {
  1730.   goto loser;
  1731.       }
  1732.     }
  1733.     tmpPtr += SSM_SIZEOF_STRING(*(SSMString*)tmpPtr);
  1734.     *pubMechFlags = PR_ntohl(*(unsigned long*)tmpPtr);
  1735.     tmpPtr += sizeof(unsigned long);
  1736.     *pubCipherFlags = PR_ntohl(*(unsigned long*)tmpPtr);
  1737.     return PR_SUCCESS;
  1738.  loser:
  1739.     if (moduleName && *moduleName) {
  1740.         PR_Free(moduleName);
  1741.     }
  1742.     if (libraryPath && *libraryPath) {
  1743.         PR_Free(libraryPath);
  1744.     }
  1745.     return PR_FAILURE;
  1746. }
  1747. PRInt32 SSM_PackAddNewModuleResponse(void **data, PRInt32 rv)
  1748. {
  1749.     return SSM_PackSingleNumReply(data, rv);
  1750. }
  1751. PRStatus SSM_ParseDeleteSecurityModuleRequest(void *data, char **moduleName)
  1752. {
  1753.     PRStatus rv = PR_FAILURE;
  1754.     if (data == NULL) {
  1755.         goto done;
  1756.     }
  1757.     if (moduleName) {
  1758.         *moduleName = NULL;
  1759. rv = SSM_SSMStringToString(moduleName, NULL, (SSMString*)data);
  1760.     }
  1761.  done:
  1762.     return rv;
  1763. }
  1764. PRInt32 SSM_PackDeleteModuleResponse(void **data, PRInt32 moduleType)
  1765. {
  1766.     return SSM_PackSingleNumReply(data, moduleType);
  1767. }
  1768. /* messages for importing certs *the traditional way* */
  1769. PRInt32 SSM_PackDecodeCertReply(void ** data, PRInt32 certID)
  1770. {
  1771.  return SSM_PackSingleNumReply(data, certID);
  1772. }
  1773. PRStatus SSM_ParseDecodeCertRequest(void * data, PRInt32 * len,
  1774.                                         char ** buffer)
  1775. {
  1776.   if (!data) 
  1777.     goto loser;
  1778.   if (buffer) {
  1779.     return SSM_SSMStringToString(buffer, len, (SSMString*)data); 
  1780.   }
  1781. loser:
  1782.   return PR_FAILURE;
  1783. }
  1784. PRStatus SSM_ParseDecodeAndCreateTempCertRequest(void * data,
  1785.                         char ** certbuf, PRUint32 * certlen, int * certClass)
  1786. {
  1787.   PRStatus rv = PR_FAILURE;
  1788.   if (!data) 
  1789.     goto loser;
  1790.   *certClass = PR_ntohl(*(int *)data);
  1791.   rv = SSM_SSMStringToString(certbuf, certlen, (SSMString *)((char *)data + sizeof(int)));
  1792.   if (rv != PR_SUCCESS)
  1793.     goto loser;
  1794. loser:  
  1795.   if (data)
  1796.     PR_Free(data);
  1797.   return rv;
  1798.   
  1799. PRStatus SSM_ParseGetKeyChoiceListRequest(void * data, PRUint32 dataLen,
  1800.                                           char ** type, PRUint32 *typeLen,
  1801.                                           char ** pqgString, PRUint32 * pqgLen)
  1802. {
  1803.   PRStatus  rv = PR_SUCCESS;
  1804.   void * curptr = data;
  1805.   char * field = NULL, * value;
  1806.   PRUint32 len;
  1807.   /* in fact, this is perfectly OK, loser is just an exit tag */
  1808.   if (!data)
  1809.     goto loser;
  1810.   if (type) *type = NULL;
  1811.   if (pqgString) *pqgString = NULL;
  1812.   
  1813.   while  ((long)curptr < (long)data + dataLen)  {
  1814.     rv = SSM_SSMStringToString(&field, &len, (SSMString *)curptr);
  1815.     if (rv != PR_SUCCESS)
  1816.       goto loser;
  1817.     curptr = (char *)curptr + SSMSTRING_PADDED_LENGTH(len) + sizeof(PRInt32);
  1818.     rv = SSM_SSMStringToString(&value, &len, (SSMString *)curptr);
  1819.     if (rv != PR_SUCCESS)
  1820.       goto loser;
  1821.     curptr = (char *)curptr + SSMSTRING_PADDED_LENGTH(len) + sizeof(PRInt32);
  1822.     if (type &&  PORT_Strcmp(field, "type")==0) {
  1823.       *type = value;
  1824.       if (typeLen) *typeLen = len;
  1825.     } else if (pqgString && PORT_Strcmp(field, "pqg")==0) {
  1826.       *pqgString = value;
  1827.       if (pqgLen) *pqgLen = len;
  1828.     }
  1829.     if (field) PR_Free(field);
  1830.   } 
  1831. loser:
  1832.   if (data)
  1833.     PR_Free(data);
  1834.   return rv;
  1835.   
  1836. PRInt32 SSM_PackGetKeyChoiceListReply(void ** data, char ** list)
  1837. {
  1838.   PRInt32 len = 0, i=0, oldlen;
  1839.   char * tmpString = NULL, * tmp = NULL;
  1840.   PRStatus rv = PR_FAILURE;
  1841.   *data = NULL;
  1842.   while (list[i] != 0) {
  1843.     oldlen = len;
  1844.     len = len + SSMSTRING_PADDED_LENGTH(strlen(list[i])) + sizeof(PRInt32);
  1845.     if (tmp)  
  1846.       tmp = PR_REALLOC(tmp, len);
  1847.     else 
  1848.       tmp = PORT_ZAlloc(len);
  1849.     if (!tmp)
  1850.       goto loser;
  1851.     rv = SSM_StringToSSMString((SSMString **)&tmpString, 0, list[i]); 
  1852.     if (rv != PR_SUCCESS)  
  1853.       goto loser;
  1854.     memcpy(tmp+oldlen, tmpString, len-oldlen);
  1855.     i++;
  1856.   }
  1857.   *data = PORT_ZAlloc(len + sizeof(i));
  1858.   oldlen = PR_htonl(i);
  1859.   *(PRInt32 *)*data = oldlen; /* number of strings */
  1860.   memcpy((char *)*data + sizeof(i), tmp, len);
  1861.   return len+sizeof(i);
  1862. loser:
  1863.    /* scream out loud, should not be breaking here 
  1864.    SSM_DEBUG("Error in packGetKeyChoiceListReply!n");
  1865.    */
  1866.    *data = NULL;
  1867.    return 0;
  1868. }
  1869. PRStatus SSM_ParseGenKeyOldStyleRequest(void * data, PRUint32 datalen,
  1870.                                         char ** choiceString,
  1871.                                         char ** challenge,
  1872.                                         char ** typeString,
  1873.                                         char ** pqgString)
  1874. {
  1875.   char * curptr = (char *)data;
  1876.   PRStatus rv; 
  1877.    
  1878.   if (!data)
  1879.     goto loser;
  1880.   
  1881.   if (choiceString) {
  1882.     rv = SSM_SSMStringToString(choiceString, NULL, (SSMString *)curptr);
  1883.     if (rv != PR_SUCCESS)
  1884.       goto loser;
  1885.   }
  1886.   curptr = (char *)curptr + SSM_SIZEOF_STRING(*(SSMString *)curptr);
  1887.   if (challenge) {
  1888.     rv = SSM_SSMStringToString(challenge, NULL, (SSMString *)curptr);
  1889.     if (rv != PR_SUCCESS)
  1890.       goto loser;
  1891.   }
  1892.   curptr = (char *)curptr + SSM_SIZEOF_STRING(*(SSMString *)curptr); 
  1893.   if (typeString) {
  1894.     rv = SSM_SSMStringToString(typeString, NULL, (SSMString *)curptr);
  1895.     if (rv != PR_SUCCESS)
  1896.       goto loser;
  1897.   }
  1898.   curptr = (char *)curptr + SSM_SIZEOF_STRING(*(SSMString *)curptr);
  1899.   if (pqgString) {
  1900.     rv = SSM_SSMStringToString(pqgString, NULL, (SSMString *)curptr);
  1901.     if (rv != PR_SUCCESS)
  1902.       goto loser;
  1903.   }
  1904.   curptr = (char *)curptr + SSM_SIZEOF_STRING(*(SSMString *)curptr);
  1905.   goto done;
  1906. loser:
  1907.   if (pqgString && *pqgString) {
  1908.     PR_Free(*pqgString);
  1909.     *pqgString = NULL;
  1910.   }
  1911.   if (typeString && *typeString) {
  1912.     PR_Free(*typeString);
  1913.     *typeString = NULL;
  1914.   }
  1915.   if (challenge && *challenge) {
  1916.     PR_Free(*challenge);
  1917.     *challenge = NULL;
  1918.   }
  1919.   if (choiceString && *choiceString) {
  1920.     PR_Free(*choiceString);
  1921.     *choiceString = NULL;
  1922.   }
  1923.   if (rv == PR_SUCCESS)
  1924.     rv = PR_FAILURE;
  1925. done:
  1926.   if (data) 
  1927.     PR_Free(data);
  1928.   return rv;
  1929. }
  1930.  
  1931. PRInt32 SSM_PackGenKeyOldStyleReply(void ** data, char * keydata)
  1932. {
  1933.   PRStatus rv;
  1934.   char * curptr;
  1935.   if (!data)
  1936.     return 0;
  1937.   rv = SSM_StringToSSMString((SSMString **)&curptr, 0, keydata);
  1938.   if (rv != PR_SUCCESS)
  1939.     return 0;
  1940.    
  1941.   *data = curptr;
  1942.   return SSM_SIZEOF_STRING(*(SSMString *)curptr);
  1943. }
  1944. PRInt32 SSM_PackFilePathRequest(void **data, PRInt32 resID, char *prompt,
  1945.                                 PRBool shouldFileExist, char *fileSuffix)
  1946. {
  1947.     PRInt32 reqLen;
  1948.     char *request;
  1949.     PRInt32 promptLen, fileSufLen;
  1950.     promptLen = strlen(prompt);
  1951.     fileSufLen = strlen(fileSuffix);
  1952.     reqLen = SSMSTRING_PADDED_LENGTH(promptLen) + 
  1953.              SSMSTRING_PADDED_LENGTH(fileSufLen) + (4*sizeof(PRInt32));
  1954.     request = SSMPORT_ZNewArray(char, reqLen);
  1955.     if (request == NULL) {
  1956.         *data = NULL;
  1957.         return 0;
  1958.     }
  1959.     *data = request;
  1960.     *(PRInt32*)request = PR_htonl(resID);
  1961.     request += sizeof(PRInt32);
  1962.     *(PRInt32*)request = PR_htonl(shouldFileExist);
  1963.     request += sizeof(PRInt32);
  1964.     *(PRInt32*)request = PR_htonl(promptLen);
  1965.     request += sizeof(PRInt32);
  1966.     memcpy(request, prompt, promptLen);
  1967.     request += SSMSTRING_PADDED_LENGTH(promptLen);
  1968.     *(PRInt32*)request = PR_htonl(fileSufLen);
  1969.     request += sizeof(PRInt32);
  1970.     memcpy(request, fileSuffix, fileSufLen);
  1971.     return reqLen;
  1972. }
  1973. PRStatus SSM_ParseFilePathReply(void *message, char **filePath,
  1974.                                 PRInt32 *rid)
  1975. {
  1976.     unsigned char *curPtr = message;
  1977.     *rid = PR_ntohl(*(PRInt32*)curPtr);
  1978.     curPtr += sizeof(PRInt32);
  1979.     if (filePath != NULL) {
  1980.         *filePath = NULL;
  1981.         SSM_SSMStringToString(filePath, NULL, (SSMString*)curPtr);
  1982.     }
  1983.     curPtr += SSM_SIZEOF_STRING(*(SSMString*)curPtr);
  1984.     return PR_SUCCESS;
  1985. }
  1986. PRInt32 SSM_PackPromptRequestEvent(void **data, PRInt32 resID, char *prompt)
  1987. {
  1988.     PRInt32 promptLen;
  1989.     PRInt32 reqLen;
  1990.     char *request;
  1991.     promptLen = strlen(prompt);
  1992.     reqLen = SSMSTRING_PADDED_LENGTH(promptLen) + (2*sizeof(PRInt32));
  1993.     *data = request = SSMPORT_ZNewArray(char, reqLen);
  1994.     if (request == NULL) {
  1995.         *data = NULL;
  1996.         return 0;
  1997.     }
  1998.     *(PRInt32*)request = PR_htonl(resID);
  1999.     request += sizeof(PRInt32); 
  2000.     *(PRInt32*)request = PR_htonl(promptLen);
  2001.     request += sizeof(PRInt32);
  2002.     memcpy(request, prompt, promptLen);
  2003.     return reqLen;
  2004. }
  2005. PRStatus 
  2006. SSM_ParsePasswordPromptReply(void *data, PRInt32 *resID, char **reply)
  2007. {
  2008.     /* The Message formats are the same, so I can do this. */
  2009.     return SSM_ParseFilePathReply(data, reply, resID);
  2010. }