2261 lines
58 KiB
C
2261 lines
58 KiB
C
/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
|
|
/*
|
|
* The contents of this file are subject to the Mozilla Public
|
|
* License Version 1.1 (the "License"); you may not use this file
|
|
* except in compliance with the License. You may obtain a copy of
|
|
* the License at http://www.mozilla.org/MPL/
|
|
*
|
|
* Software distributed under the License is distributed on an "AS
|
|
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
|
|
* implied. See the License for the specific language governing
|
|
* rights and limitations under the License.
|
|
*
|
|
* The Original Code is the Netscape security libraries.
|
|
*
|
|
* The Initial Developer of the Original Code is Netscape
|
|
* Communications Corporation. Portions created by Netscape are
|
|
* Copyright (C) 1994-2000 Netscape Communications Corporation. All
|
|
* Rights Reserved.
|
|
*
|
|
* Contributor(s):
|
|
*
|
|
* Alternatively, the contents of this file may be used under the
|
|
* terms of the GNU General Public License Version 2 or later (the
|
|
* "GPL"), in which case the provisions of the GPL are applicable
|
|
* instead of those above. If you wish to allow use of your
|
|
* version of this file only under the terms of the GPL and not to
|
|
* allow others to use your version of this file under the MPL,
|
|
* indicate your decision by deleting the provisions above and
|
|
* replace them with the notice and other provisions required by
|
|
* the GPL. If you do not delete the provisions above, a recipient
|
|
* may use your version of this file under either the MPL or the
|
|
* GPL.
|
|
*/
|
|
/*************************************************************************
|
|
* Only server-side message functions are provided: Parse functions for
|
|
* request messages and Pack functions for reply messages.
|
|
*
|
|
* Parse functions accept a ptr to the "blob" of data received from the
|
|
* network and return fields of the message, numerals in host-order,
|
|
* strings as C-style character strings. If everything goes well,
|
|
* blob of data is freed and SUCCESS is returned, otherwise an error returned
|
|
* and data left intact. Caller may pass NULL ptrs for the fields s/he is
|
|
* not interested in.
|
|
*
|
|
* Pack functions take all the info to construct a message and fill in a
|
|
* ptr to the "blob" of data to be sent. Return size of the "blob" or 0
|
|
* if something goes wrong. All fields of the message must be supplied,
|
|
* otherwise an error is returned.
|
|
*
|
|
* All functions set NSPR errors when necessary.
|
|
* Caller is responsible for freeing returned values.
|
|
************************************************************************/
|
|
|
|
#include "protocolf.h"
|
|
#include "rsrcids.h"
|
|
#include "nspr.h"
|
|
|
|
|
|
/* Utility functions to handle generic requests/replies */
|
|
SSMPRStatus SSM_ParseSingleNumRequest(void *request,
|
|
SSMPRUint32 *result)
|
|
{
|
|
PRStatus rv = PR_SUCCESS;
|
|
|
|
if (!request)
|
|
rv = PR_INVALID_ARGUMENT_ERROR;
|
|
else if (result)
|
|
*result = SSMPR_ntohl(*(SSMPRUint32 *)request);
|
|
|
|
/* ### mwelch Don't free this here, because the message-specific
|
|
handlers will free this for us. */
|
|
/* if (request)
|
|
PR_Free(request);*/
|
|
return rv;
|
|
}
|
|
|
|
SSMPRInt32 SSM_PackSingleNumReply(void **reply, SSMPRUint32 num)
|
|
{
|
|
SSMPRStatus rv = PR_SUCCESS;
|
|
if (!reply)
|
|
rv = SSMPR_INVALID_ARGUMENT_ERROR;
|
|
else
|
|
{
|
|
/* allocate memory for blob of data */
|
|
*reply = (void *)SSMPORT_ZAlloc(sizeof(SSMPRUint32));
|
|
if (!*reply)
|
|
rv = SSMPR_OUT_OF_MEMORY_ERROR;
|
|
}
|
|
|
|
if (rv == PR_SUCCESS)
|
|
{
|
|
*(SSMPRInt32 *)*reply = SSMPR_htonl(num);
|
|
return sizeof(SSMPRUint32);
|
|
}
|
|
else
|
|
{
|
|
SSMPORT_SetError(rv);
|
|
return 0;
|
|
}
|
|
}
|
|
|
|
|
|
/* Initial messages - establishing connection */
|
|
|
|
SSMPRStatus SSM_ParseHelloRequest(void * helloRequest,
|
|
SSMPRUint32 * version,
|
|
PRBool *doesUI,
|
|
PRInt32 * policyType,
|
|
SSMPRUint32 * profileLen,
|
|
char ** profile)
|
|
{
|
|
void * curptr = helloRequest;
|
|
SSMPRStatus rv = SSMPR_SUCCESS;
|
|
|
|
if (!helloRequest) {
|
|
rv = PR_INVALID_ARGUMENT_ERROR;
|
|
goto loser;
|
|
}
|
|
|
|
/* read and store protocol version */
|
|
if (version)
|
|
*version = SSMPR_ntohl(*((SSMPRUint32 *)curptr));
|
|
curptr = (SSMPRUint32 *)curptr + 1;
|
|
if (policyType)
|
|
*policyType = PR_ntohl(*((PRInt32 *)curptr));
|
|
curptr = (SSMPRUint32 *)curptr + 1;
|
|
if (doesUI)
|
|
*doesUI = PR_ntohl(*((SSMPRInt32 *)curptr));
|
|
curptr = (SSMPRUint32 *)curptr + 1;
|
|
if (profile) {
|
|
*profile = NULL;
|
|
/* read and store profile name that client uses */
|
|
rv = SSM_SSMStringToString(profile, NULL, (SSMString *)curptr);
|
|
if (rv != SSMPR_SUCCESS && *profile)
|
|
SSMPORT_Free(*profile);
|
|
}
|
|
loser:
|
|
if (helloRequest)
|
|
SSMPORT_Free(helloRequest);
|
|
return rv;
|
|
}
|
|
|
|
|
|
SSMPRInt32 SSM_PackHelloReply(void ** helloReply, SSMPRInt32 result,
|
|
SSMPRUint32 sessionID, SSMPRUint32 version,
|
|
SSMPRUint32 httpPort,
|
|
SSMPRUint32 nonceLength, char * nonce,
|
|
SSMPolicyType policy)
|
|
{
|
|
SSMPRInt32 blobSize;
|
|
void * curptr, * nonceStr;
|
|
SSMPRStatus rv;
|
|
|
|
if (!helloReply || !nonce || !*nonce || policy == ssmUnknownPolicy) {
|
|
rv = PR_INVALID_ARGUMENT_ERROR;
|
|
goto loser;
|
|
}
|
|
|
|
blobSize = sizeof(SSMPRInt32)+ sizeof(SSMPRUint32) * 5 +
|
|
SSMSTRING_PADDED_LENGTH(strlen(nonce));
|
|
curptr = (void *)SSMPORT_ZAlloc(blobSize);
|
|
if (!curptr) {
|
|
rv = PR_OUT_OF_MEMORY_ERROR;
|
|
*helloReply = NULL;
|
|
goto loser;
|
|
}
|
|
*helloReply = curptr;
|
|
|
|
*(SSMPRInt32 *)curptr = SSMPR_htonl(result);
|
|
curptr = (SSMPRInt32 *)curptr + 1;
|
|
*(SSMPRUint32 *)curptr = SSMPR_htonl(sessionID);
|
|
curptr = (SSMPRUint32 *)curptr + 1;
|
|
*(SSMPRUint32 *)curptr = SSMPR_htonl(version);
|
|
curptr = (SSMPRUint32 *)curptr + 1;
|
|
*(SSMPRUint32 *)curptr = SSMPR_htonl(httpPort);
|
|
curptr = (SSMPRUint32 *)curptr + 1;
|
|
*(SSMPRUint32 *)curptr = SSMPR_htonl(policy);
|
|
curptr = (SSMPRUint32 *)curptr + 1;
|
|
|
|
rv = SSM_StringToSSMString((SSMString **)&nonceStr, 0, nonce);
|
|
if (rv != SSMPR_SUCCESS) {
|
|
if (nonceStr) SSMPORT_Free(nonceStr); /* free string */
|
|
goto loser;
|
|
}
|
|
memcpy(curptr, nonceStr, SSM_SIZEOF_STRING(*(SSMString *)nonceStr));
|
|
SSMPORT_Free(nonceStr);
|
|
|
|
return blobSize;
|
|
loser:
|
|
if (*helloReply)
|
|
PR_Free(*helloReply);
|
|
return 0;
|
|
}
|
|
|
|
|
|
/* Handle data connection messages */
|
|
/* SSL data connection request */
|
|
SSMPRStatus SSM_ParseSSLDataConnectionRequest(void *sslRequest,
|
|
SSMPRUint32 * flags,
|
|
SSMPRUint32 * port,
|
|
SSMPRUint32 * hostIPLen,
|
|
char ** hostIP,
|
|
SSMPRUint32 * hostNameLen,
|
|
char ** hostName)
|
|
{
|
|
SSMPRStatus rv = SSMPR_SUCCESS;
|
|
void * curptr;
|
|
|
|
if (!sslRequest) {
|
|
rv = PR_INVALID_ARGUMENT_ERROR;
|
|
goto loser;
|
|
}
|
|
curptr = sslRequest;
|
|
if (flags) *flags = SSMPR_ntohl(*(SSMPRUint32 *)curptr);
|
|
curptr = (SSMPRUint32 *)curptr + 1;
|
|
if (port) *port = SSMPR_ntohl(*(SSMPRUint32 *)curptr);
|
|
curptr = (SSMPRUint32 *)curptr + 1;
|
|
|
|
if (hostIP) {
|
|
*hostIP = NULL;
|
|
/* read and store hostIP */
|
|
rv = SSM_SSMStringToString(hostIP, NULL, (SSMString *)curptr);
|
|
if (rv != SSMPR_SUCCESS)
|
|
goto loser;
|
|
}
|
|
curptr = (char *)curptr + SSM_SIZEOF_STRING(*(SSMString *)curptr);
|
|
|
|
if (hostName) {
|
|
*hostName = NULL;
|
|
/* read and store hostName */
|
|
rv = SSM_SSMStringToString(hostName, NULL, (SSMString *)curptr);
|
|
if (rv != SSMPR_SUCCESS)
|
|
goto loser;
|
|
}
|
|
goto done;
|
|
loser:
|
|
if (hostName && *hostName)
|
|
PR_Free(*hostName);
|
|
if (hostIP && *hostIP)
|
|
PR_Free(*hostIP);
|
|
done:
|
|
if (sslRequest)
|
|
SSMPORT_Free(sslRequest);
|
|
return rv;
|
|
}
|
|
|
|
/* Hash stream data connection request */
|
|
SSMPRStatus SSM_ParseHashStreamRequest(void * hashStreamRequest,
|
|
SSMPRUint32 * type)
|
|
{
|
|
PRStatus rv = PR_SUCCESS;
|
|
|
|
if (!hashStreamRequest) {
|
|
rv = PR_INVALID_ARGUMENT_ERROR;
|
|
goto loser;
|
|
}
|
|
if (type) *type = SSMPR_ntohl(*(SSMPRUint32 *)hashStreamRequest);
|
|
|
|
loser:
|
|
if (hashStreamRequest)
|
|
SSMPORT_Free(hashStreamRequest);
|
|
return rv;
|
|
}
|
|
|
|
/* Messages to initiate PKCS7 data connection */
|
|
/* PKCS7DecodeRequest message has no data */
|
|
|
|
/* Create PKCS7 encode connection. Needs a content info */
|
|
SSMPRStatus SSM_ParseP7EncodeConnectionRequest(void *request,
|
|
SSMPRUint32 *ciRID)
|
|
{
|
|
return SSM_ParseSingleNumRequest(request, ciRID);
|
|
}
|
|
|
|
/* Create data connection reply - same for all types of data connections */
|
|
SSMPRInt32 SSM_PackDataConnectionReply(void ** sslReply,
|
|
SSMPRInt32 result,
|
|
SSMPRUint32 connID,
|
|
SSMPRUint32 port)
|
|
{
|
|
void * curptr = NULL;
|
|
SSMPRInt32 blobSize;
|
|
|
|
if (!sslReply) {
|
|
SSMPORT_SetError(SSMPR_INVALID_ARGUMENT_ERROR);
|
|
return 0;
|
|
}
|
|
|
|
blobSize = sizeof(SSMPRInt32) + sizeof(SSMPRUint32)*2;
|
|
/* allocate space for the SSLDataConnectionReply "blob" */
|
|
curptr = (void *)SSMPORT_ZAlloc(blobSize);
|
|
if (!curptr) {
|
|
SSMPORT_SetError(SSMPR_OUT_OF_MEMORY_ERROR);
|
|
*sslReply = NULL;
|
|
return 0;
|
|
}
|
|
*sslReply = curptr;
|
|
*(SSMPRInt32 *)curptr = SSMPR_htonl(result);
|
|
curptr = (SSMPRInt32 *)curptr + 1;
|
|
*(SSMPRUint32 *)curptr = SSMPR_htonl(connID);
|
|
curptr = (SSMPRUint32 *)curptr + 1;
|
|
*(SSMPRUint32 *)curptr = SSMPR_htonl(port);
|
|
|
|
return blobSize;
|
|
}
|
|
|
|
|
|
/* Messages to create SocketStatus resource */
|
|
SSMPRStatus SSM_ParseSSLSocketStatusRequest(void * statusRequest,
|
|
SSMPRUint32 * connID)
|
|
{
|
|
PRStatus rv = PR_SUCCESS;
|
|
|
|
if (!statusRequest ) {
|
|
rv = PR_INVALID_ARGUMENT_ERROR;
|
|
goto loser;
|
|
}
|
|
if (connID) *connID = SSMPR_ntohl(*((SSMPRUint32 *)statusRequest));
|
|
loser:
|
|
if (statusRequest)
|
|
SSMPORT_Free(statusRequest);
|
|
return rv;
|
|
}
|
|
|
|
SSMPRInt32 SSM_PackSSLSocketStatusReply(void ** statusReply,
|
|
SSMPRInt32 result,
|
|
SSMPRUint32 resourceID)
|
|
{
|
|
SSMPRInt32 blobSize;
|
|
void * curptr;
|
|
|
|
if (!statusReply){
|
|
SSMPORT_SetError(SSMPR_INVALID_ARGUMENT_ERROR);
|
|
return 0;
|
|
}
|
|
/* allocate memory for blob of data */
|
|
blobSize = sizeof(SSMPRUint32) + sizeof(SSMPRInt32);
|
|
curptr = (void *)SSMPORT_ZAlloc(blobSize);
|
|
if (!curptr) {
|
|
SSMPORT_SetError(SSMPR_OUT_OF_MEMORY_ERROR);
|
|
*statusReply = NULL;
|
|
return 0;
|
|
}
|
|
*statusReply = curptr;
|
|
*(SSMPRInt32 *)curptr = SSMPR_htonl(result);
|
|
curptr = (SSMPRInt32 *)curptr + 1;
|
|
*(SSMPRUint32 *)curptr = SSMPR_htonl(resourceID);
|
|
|
|
return blobSize;
|
|
}
|
|
|
|
|
|
/* UI event message - server initiated */
|
|
SSMPRInt32 SSM_PackUIEvent(void ** eventData, SSMPRUint32 resourceID,
|
|
SSMPRUint32 width, SSMPRUint32 height,
|
|
SSMPRUint32 urlLen, char * url)
|
|
{
|
|
void * curptr, * tmpStr;
|
|
SSMPRInt32 blobSize;
|
|
SSMPRStatus rv;
|
|
|
|
if (!eventData){
|
|
SSMPORT_SetError(SSMPR_INVALID_ARGUMENT_ERROR);
|
|
return 0;
|
|
}
|
|
/* allocate memory for blob of data */
|
|
blobSize = sizeof(SSMPRUint32) * 4 + SSMSTRING_PADDED_LENGTH(strlen(url));
|
|
|
|
curptr = (void *)SSMPORT_ZAlloc(blobSize);
|
|
if (!curptr) {
|
|
SSMPORT_SetError(SSMPR_OUT_OF_MEMORY_ERROR);
|
|
*eventData = NULL;
|
|
return 0;
|
|
}
|
|
*eventData = curptr;
|
|
*(SSMPRUint32 *)curptr = SSMPR_htonl(resourceID);
|
|
curptr = (SSMPRUint32 *)curptr + 1;
|
|
*(SSMPRUint32 *)curptr = SSMPR_htonl(width);
|
|
curptr = (SSMPRUint32 *)curptr + 1;
|
|
*(SSMPRUint32 *)curptr = SSMPR_htonl(height);
|
|
curptr = (SSMPRUint32 *)curptr + 1;
|
|
|
|
/* copy URL string into the blob */
|
|
rv = SSM_StringToSSMString((SSMString **)&tmpStr, 0, url);
|
|
if (rv != SSMPR_SUCCESS) {
|
|
if (tmpStr) SSMPORT_Free(tmpStr); /* free string */
|
|
SSMPORT_Free(*eventData); /* free blob */
|
|
*eventData = NULL;
|
|
return 0;
|
|
}
|
|
memcpy(curptr, tmpStr, SSM_SIZEOF_STRING(*(SSMString *)tmpStr));
|
|
SSMPORT_Free(tmpStr);
|
|
|
|
return blobSize;
|
|
}
|
|
|
|
SSMPRInt32 SSM_PackTaskCompletedEvent(void **event, SSMPRUint32 resourceID,
|
|
SSMPRUint32 numTasks,
|
|
SSMPRUint32 result)
|
|
{
|
|
void * curptr;
|
|
SSMPRInt32 blobSize;
|
|
|
|
if (!event){
|
|
SSMPORT_SetError(SSMPR_INVALID_ARGUMENT_ERROR);
|
|
return 0;
|
|
}
|
|
/* allocate memory for blob of data */
|
|
blobSize = sizeof(SSMPRUint32) * 3;
|
|
curptr = (void *)SSMPORT_ZAlloc(blobSize);
|
|
if (!curptr) {
|
|
SSMPORT_SetError(SSMPR_OUT_OF_MEMORY_ERROR);
|
|
*event = NULL;
|
|
return 0;
|
|
}
|
|
*event = curptr;
|
|
*(SSMPRUint32 *)curptr = SSMPR_htonl(resourceID);
|
|
curptr = (SSMPRUint32 *)curptr + 1;
|
|
*(SSMPRUint32 *)curptr = SSMPR_htonl(numTasks);
|
|
curptr = (SSMPRUint32 *)curptr + 1;
|
|
*(SSMPRUint32 *)curptr = SSMPR_htonl(result);
|
|
|
|
return blobSize;
|
|
}
|
|
|
|
/* Handle verify signature messages */
|
|
SSMPRStatus SSM_ParseVerifyRawSigRequest(void * verifyRawSigRequest,
|
|
SSMPRUint32 * algorithmID,
|
|
SSMPRUint32 *paramsLen,
|
|
unsigned char ** params,
|
|
SSMPRUint32 * pubKeyLen,
|
|
unsigned char ** pubKey,
|
|
SSMPRUint32 * hashLen,
|
|
unsigned char ** hash,
|
|
SSMPRUint32 * signatureLen,
|
|
unsigned char ** signature)
|
|
{
|
|
void * curptr = verifyRawSigRequest;
|
|
SSMPRStatus rv = SSMPR_SUCCESS;
|
|
|
|
if (!verifyRawSigRequest) {
|
|
rv = PR_INVALID_ARGUMENT_ERROR;
|
|
goto loser;
|
|
}
|
|
|
|
if (algorithmID) *algorithmID = SSMPR_ntohl(*(SSMPRUint32 *)curptr);
|
|
curptr = (SSMPRUint32 *)curptr + 1;
|
|
|
|
if (params) {
|
|
*params = NULL;
|
|
/* read and store cipher */
|
|
rv = SSM_SSMStringToString((char **)params, NULL, (SSMString *)curptr);
|
|
if (rv != SSMPR_SUCCESS)
|
|
goto loser;
|
|
}
|
|
curptr = (char *)curptr + SSM_SIZEOF_STRING(*(SSMString *)curptr);
|
|
|
|
if (pubKey) {
|
|
*pubKey = NULL;
|
|
/* read and store cipher */
|
|
rv = SSM_SSMStringToString((char **)pubKey, NULL, (SSMString *)curptr);
|
|
if (rv != SSMPR_SUCCESS)
|
|
goto loser;
|
|
}
|
|
curptr = (char *)curptr + SSM_SIZEOF_STRING(*(SSMString *)curptr);
|
|
if (signature) {
|
|
*signature = NULL;
|
|
/* read and store cipher */
|
|
rv = SSM_SSMStringToString((char **)signature, NULL, (SSMString *)curptr);
|
|
if (rv != SSMPR_SUCCESS)
|
|
goto loser;
|
|
}
|
|
goto done;
|
|
|
|
loser:
|
|
if (params && *params)
|
|
SSMPORT_Free(*params);
|
|
if (pubKey && *pubKey)
|
|
SSMPORT_Free(*pubKey);
|
|
if (signature && *signature)
|
|
SSMPORT_Free(*signature);
|
|
done:
|
|
if (verifyRawSigRequest)
|
|
PR_Free(verifyRawSigRequest);
|
|
return rv;
|
|
}
|
|
|
|
SSMPRInt32 SSM_PackVerifyRawSigReply(void ** verifyRawSigReply,
|
|
SSMPRInt32 result)
|
|
{
|
|
SSMPRInt32 blobSize;
|
|
void * curptr;
|
|
|
|
if (!verifyRawSigReply) {
|
|
SSMPORT_SetError(SSMPR_INVALID_ARGUMENT_ERROR);
|
|
return 0;
|
|
}
|
|
|
|
*verifyRawSigReply = NULL;
|
|
blobSize = sizeof(SSMPRInt32);
|
|
/* allocate space for the verifyRawSigReply "blob" */
|
|
curptr = (void *)SSMPORT_ZAlloc(blobSize);
|
|
if (!curptr) {
|
|
SSMPORT_SetError(SSMPR_OUT_OF_MEMORY_ERROR);
|
|
return 0;
|
|
}
|
|
*verifyRawSigReply = curptr;
|
|
*(SSMPRInt32 *)curptr = SSMPR_htonl(result);
|
|
|
|
return blobSize;
|
|
}
|
|
|
|
SSMPRStatus SSM_ParseVerifyDetachedSigRequest(void * verifyDetachedSigRequest,
|
|
SSMPRInt32 * pkcs7ContentID,
|
|
SSMPRInt32 * certUsage,
|
|
SSMPRInt32 * hashAlgID,
|
|
SSMPRUint32 * keepCert,
|
|
SSMPRUint32 * hashLen,
|
|
unsigned char ** hash)
|
|
{
|
|
void * curptr = verifyDetachedSigRequest;
|
|
SSMPRStatus rv = SSMPR_SUCCESS;
|
|
|
|
if (!verifyDetachedSigRequest) {
|
|
rv = PR_INVALID_ARGUMENT_ERROR;
|
|
goto loser;
|
|
}
|
|
|
|
if (pkcs7ContentID) *pkcs7ContentID = SSMPR_ntohl(*(SSMPRUint32 *)curptr);
|
|
curptr = (SSMPRUint32 *)curptr + 1;
|
|
|
|
if (certUsage) *certUsage = SSMPR_ntohl(*(SSMPRInt32 *)curptr);
|
|
curptr = (SSMPRInt32 *)curptr + 1;
|
|
|
|
if (hashAlgID) *hashAlgID = SSMPR_ntohl(*(SSMPRInt32 *)curptr);
|
|
curptr = (SSMPRInt32 *)curptr + 1;
|
|
|
|
if (keepCert) *keepCert = SSMPR_ntohl(*(SSMPRUint32 *)curptr);
|
|
curptr = (SSMPRUint32 *)curptr + 1;
|
|
|
|
if (hash) {
|
|
*hash = NULL;
|
|
/* read and store cipher */
|
|
rv = SSM_SSMStringToString((char **)hash, (PRInt32 *)hashLen, (SSMString *)curptr);
|
|
if (rv != SSMPR_SUCCESS)
|
|
goto loser;
|
|
}
|
|
goto done;
|
|
|
|
loser:
|
|
if (hash && *hash)
|
|
PR_Free(*hash);
|
|
done:
|
|
if (verifyDetachedSigRequest)
|
|
PR_Free(verifyDetachedSigRequest);
|
|
return rv;
|
|
}
|
|
|
|
|
|
SSMPRInt32 SSM_PackVerifyDetachedSigReply(void ** verifyDetachedSigReply,
|
|
SSMPRInt32 result)
|
|
{
|
|
SSMPRInt32 blobSize;
|
|
void * curptr;
|
|
|
|
if (!verifyDetachedSigReply) {
|
|
SSMPORT_SetError(SSMPR_INVALID_ARGUMENT_ERROR);
|
|
return 0;
|
|
}
|
|
*verifyDetachedSigReply = NULL;
|
|
blobSize = sizeof(SSMPRInt32);
|
|
/* allocate space for the helloRequest "blob" */
|
|
curptr = (void *)SSMPORT_ZAlloc(blobSize);
|
|
if (!curptr) {
|
|
SSMPORT_SetError(SSMPR_OUT_OF_MEMORY_ERROR);
|
|
return 0;
|
|
}
|
|
*verifyDetachedSigReply = curptr;
|
|
*(SSMPRInt32 *)curptr = SSMPR_htonl(result);
|
|
|
|
return blobSize;
|
|
}
|
|
|
|
/* Messages for the resource management */
|
|
|
|
|
|
SSMPRStatus SSM_ParseCreateSignedRequest(void *request,
|
|
SSMPRInt32 *scertRID,
|
|
SSMPRInt32 *ecertRID,
|
|
SSMPRUint32 *dig_alg,
|
|
SECItem **digest)
|
|
{
|
|
unsigned char *curPtr = (unsigned char *) request;
|
|
SSMPRStatus rv;
|
|
|
|
if (!request) {
|
|
SSMPORT_SetError(SSMPR_INVALID_ARGUMENT_ERROR);
|
|
return SSMPR_FAILURE;
|
|
}
|
|
*scertRID = SSMPR_ntohl(*(SSMPRInt32*)curPtr);
|
|
curPtr += sizeof(SSMPRInt32);
|
|
*ecertRID = SSMPR_ntohl(*(SSMPRInt32*)curPtr);
|
|
curPtr += sizeof(SSMPRInt32);
|
|
*dig_alg = SSMPR_ntohl(*(SSMPRUint32*)curPtr);
|
|
curPtr += sizeof(SSMPRUint32);
|
|
*digest = PR_NEWZAP(SECItem);
|
|
if (*digest == NULL)
|
|
goto loser;
|
|
rv = SSM_SSMStringToString(&(*digest)->data, &(*digest)->len,
|
|
(SSMString *) curPtr);
|
|
if (rv != SSMPR_SUCCESS)
|
|
goto loser;
|
|
return PR_SUCCESS;
|
|
loser:
|
|
return PR_FAILURE;
|
|
}
|
|
|
|
SSMPRInt32 SSM_PackCreateSignedReply(void **reply, SSMPRInt32 ciRID,
|
|
SSMPRUint32 result)
|
|
{
|
|
SSMPRInt32 blobSize;
|
|
unsigned char *curPtr;
|
|
|
|
blobSize = sizeof (SSMPRInt32) + sizeof(SSMPRUint32);
|
|
*reply = curPtr = PORT_ZAlloc(blobSize);
|
|
if (curPtr == NULL) {
|
|
SSMPORT_SetError(SSMPR_OUT_OF_MEMORY_ERROR);
|
|
return 0;
|
|
}
|
|
*((SSMPRInt32*)curPtr) = SSMPR_htonl(ciRID);
|
|
curPtr += sizeof(SSMPRInt32);
|
|
*((SSMPRInt32*)curPtr) = SSMPR_htonl(result);
|
|
|
|
return blobSize;
|
|
}
|
|
|
|
SSMPRStatus SSM_ParseCreateEncryptedRequest(void *request,
|
|
SSMPRInt32 *scertRID,
|
|
SSMPRInt32 *nrcerts,
|
|
SSMPRInt32 **rcertRIDs)
|
|
{
|
|
unsigned char *curPtr = (unsigned char *) request;
|
|
SSMPRStatus rv;
|
|
SSMPRInt32 ncerts;
|
|
int i;
|
|
|
|
if (!request) {
|
|
SSMPORT_SetError(SSMPR_INVALID_ARGUMENT_ERROR);
|
|
return SSMPR_FAILURE;
|
|
}
|
|
*scertRID = SSMPR_ntohl(*(SSMPRInt32*)curPtr);
|
|
curPtr += sizeof(SSMPRInt32);
|
|
ncerts = SSMPR_ntohl(*(SSMPRInt32*)curPtr);
|
|
*rcertRIDs = PR_Calloc(ncerts+1, sizeof(SSMPRInt32));
|
|
curPtr += sizeof(SSMPRInt32);
|
|
for (i = 0; i < ncerts; i++) {
|
|
(*rcertRIDs)[i] = SSMPR_ntohl(*(SSMPRInt32*)curPtr);
|
|
curPtr += sizeof(SSMPRInt32);
|
|
}
|
|
*nrcerts = ncerts;
|
|
return SSMPR_SUCCESS;
|
|
}
|
|
|
|
SSMPRInt32 SSM_PackCreateEncryptedReply(void **reply, SSMPRInt32 ciRID,
|
|
SSMPRUint32 result)
|
|
{
|
|
SSMPRInt32 blobSize;
|
|
unsigned char *curPtr;
|
|
|
|
blobSize = sizeof (SSMPRInt32) + sizeof(SSMPRUint32);
|
|
*reply = curPtr = PORT_ZAlloc(blobSize);
|
|
if (curPtr == NULL) {
|
|
SSMPORT_SetError(SSMPR_OUT_OF_MEMORY_ERROR);
|
|
return 0;
|
|
}
|
|
*((SSMPRInt32*)curPtr) = SSMPR_htonl(ciRID);
|
|
curPtr += sizeof(SSMPRInt32);
|
|
*((SSMPRInt32*)curPtr) = SSMPR_htonl(result);
|
|
|
|
return blobSize;
|
|
}
|
|
|
|
SSMPRStatus SSM_ParseCreateResourceRequest(void *request,
|
|
SSMPRUint32 *type,
|
|
unsigned char **params,
|
|
SSMPRUint32 *paramLen)
|
|
{
|
|
unsigned char *curPtr = (unsigned char*)request;
|
|
SSMPRStatus rv = SSMPR_SUCCESS;
|
|
|
|
if (!request)
|
|
{
|
|
SSMPORT_SetError(SSMPR_INVALID_ARGUMENT_ERROR);
|
|
return SSMPR_FAILURE;
|
|
}
|
|
|
|
/* Get stuff out. */
|
|
if (type)
|
|
*type = SSMPR_ntohl(*((SSMPRInt32*)curPtr));
|
|
curPtr += sizeof(SSMPRInt32);
|
|
|
|
if (params)
|
|
rv = SSM_SSMStringToString((char **) params, (int*) paramLen,
|
|
(SSMString *) curPtr);
|
|
|
|
return rv;
|
|
}
|
|
|
|
SSMPRStatus SSM_PackCreateResourceReply(void **reply, SSMPRStatus rv,
|
|
SSMPRUint32 resID)
|
|
{
|
|
SSMPRInt32 blobSize;
|
|
unsigned char *curPtr;
|
|
|
|
blobSize = sizeof (SSMPRInt32) + sizeof(SSMPRUint32);
|
|
*reply = curPtr = PORT_ZAlloc(blobSize);
|
|
if (curPtr == NULL) {
|
|
SSMPORT_SetError(SSMPR_OUT_OF_MEMORY_ERROR);
|
|
return 0;
|
|
}
|
|
*((SSMPRInt32*)curPtr) = SSMPR_htonl(rv);
|
|
curPtr += sizeof(SSMPRInt32);
|
|
*((SSMPRInt32*)curPtr) = SSMPR_htonl(resID);
|
|
|
|
return blobSize;
|
|
}
|
|
|
|
SSMPRStatus SSM_ParseDuplicateResourceRequest(void *request,
|
|
SSMPRUint32 *resourceID)
|
|
{
|
|
return SSM_ParseSingleNumRequest(request, resourceID);
|
|
}
|
|
|
|
SSMPRInt32 SSM_PackDuplicateResourceReply(void ** reply, SSMPRInt32 result,
|
|
SSMPRUint32 resID)
|
|
{
|
|
SSMPRInt32 blobSize;
|
|
unsigned char *curPtr;
|
|
|
|
blobSize = sizeof (SSMPRInt32) + sizeof(SSMPRUint32);
|
|
*reply = curPtr = PORT_ZAlloc(blobSize);
|
|
if (curPtr == NULL) {
|
|
SSMPORT_SetError(SSMPR_OUT_OF_MEMORY_ERROR);
|
|
return 0;
|
|
}
|
|
*((SSMPRInt32*)curPtr) = SSMPR_htonl(result);
|
|
curPtr += sizeof(SSMPRInt32);
|
|
*((SSMPRInt32*)curPtr) = SSMPR_htonl(resID);
|
|
|
|
return blobSize;
|
|
}
|
|
|
|
SSMPRStatus SSM_ParseGetAttribRequest(void * getAttribRequest,
|
|
SSMPRUint32 * resourceID,
|
|
SSMPRUint32 * fieldID)
|
|
{
|
|
void * curptr = getAttribRequest;
|
|
PRStatus rv = PR_SUCCESS;
|
|
|
|
if (!getAttribRequest) {
|
|
rv = PR_INVALID_ARGUMENT_ERROR;
|
|
goto loser;
|
|
}
|
|
if (resourceID) *resourceID = SSMPR_ntohl(*(SSMPRUint32 *)curptr);
|
|
curptr = (SSMPRUint32 *)curptr + 1;
|
|
|
|
if (fieldID) *fieldID = SSMPR_ntohl(*(SSMPRInt32 *)curptr);
|
|
curptr = (SSMPRInt32 *)curptr + 1;
|
|
|
|
loser:
|
|
if (getAttribRequest)
|
|
PR_Free(getAttribRequest);
|
|
return rv;
|
|
}
|
|
|
|
SSMPRInt32 SSM_PackGetAttribReply(void **getAttribReply,
|
|
SSMPRInt32 result,
|
|
SSMAttributeValue *value)
|
|
{
|
|
SSMPRInt32 blobSize, fieldlength;
|
|
void * curptr;
|
|
|
|
if (!getAttribReply) {
|
|
SSMPORT_SetError(SSMPR_INVALID_ARGUMENT_ERROR);
|
|
return 0;
|
|
}
|
|
*getAttribReply = NULL;
|
|
|
|
/* Calculate length of the field value. Binary length (fielddatalen)
|
|
takes precedence over using strlen(). */
|
|
fieldlength = (value->type == SSM_STRING_ATTRIBUTE) ?
|
|
PR_ntohl(SSMSTRING_PADDED_LENGTH(value->u.string->m_length)) : 0;
|
|
fieldlength += sizeof(SSMPRUint32);
|
|
|
|
blobSize = sizeof(SSMPRInt32) + fieldlength;
|
|
/* allocate space for the getAttribReply "blob" */
|
|
curptr = (void *)SSMPORT_ZAlloc(blobSize);
|
|
if (!curptr) {
|
|
SSMPORT_SetError(SSMPR_OUT_OF_MEMORY_ERROR);
|
|
return 0;
|
|
}
|
|
* getAttribReply = curptr;
|
|
*(SSMPRInt32 *)curptr = SSMPR_htonl(result);
|
|
curptr = (SSMPRInt32 *)curptr + 1;
|
|
|
|
switch(value->type) {
|
|
case SSM_STRING_ATTRIBUTE:
|
|
/* This value is stored in network byte order, no need to switch
|
|
* it back
|
|
*/
|
|
*(SSMPRUint32 *)curptr = value->u.string->m_length;
|
|
curptr = (SSMPRInt32 *)curptr + 1;
|
|
memcpy(curptr, &value->u.string->m_data,
|
|
PR_ntohl(value->u.string->m_length));
|
|
break;
|
|
case SSM_RID_ATTRIBUTE:
|
|
*(SSMPRUint32 *)curptr = SSMPR_htonl(value->u.rid);
|
|
break;
|
|
case SSM_NUMERIC_ATTRIBUTE:
|
|
*(SSMPRUint32 *)curptr = SSMPR_htonl(value->u.numeric);
|
|
break;
|
|
}
|
|
|
|
return blobSize;
|
|
}
|
|
|
|
SSMPRStatus
|
|
SSM_ParseSetAttribRequest(SECItem *msg,
|
|
SSMPRInt32 *resourceID,
|
|
SSMPRInt32 *fieldID,
|
|
SSMAttributeValue *value)
|
|
{
|
|
unsigned char *curPtr;
|
|
SSMPRInt32 strLen;
|
|
|
|
if (!msg || !msg->data || !resourceID || !fieldID || !value){
|
|
SSMPORT_SetError(SSMPR_INVALID_ARGUMENT_ERROR);
|
|
return SSMPR_FAILURE;
|
|
}
|
|
curPtr = msg->data;
|
|
value->type = msg->type & SSM_SPECIFIC_MASK;
|
|
|
|
switch (value->type) {
|
|
case SSM_NUMERIC_ATTRIBUTE:
|
|
*resourceID = SSMPR_ntohl(*(SSMPRInt32*)curPtr);
|
|
curPtr += sizeof(SSMPRInt32);
|
|
*fieldID = SSMPR_ntohl(*(SSMPRInt32*)curPtr);
|
|
curPtr += sizeof(SSMPRInt32);
|
|
value->u.numeric = SSMPR_ntohl(*(SSMPRInt32*)curPtr);
|
|
break;
|
|
case SSM_RID_ATTRIBUTE:
|
|
*resourceID = SSMPR_ntohl(*(SSMPRInt32*)curPtr);
|
|
curPtr += sizeof(SSMPRInt32);
|
|
*fieldID = SSMPR_ntohl(*(SSMPRInt32*)curPtr);
|
|
curPtr += sizeof(SSMPRInt32);
|
|
value->u.rid = SSMPR_ntohl(*(SSMPRInt32*)curPtr);
|
|
break;
|
|
case SSM_STRING_ATTRIBUTE:
|
|
*resourceID = SSMPR_ntohl(*(SSMPRInt32*)curPtr);
|
|
curPtr += sizeof(SSMPRInt32);
|
|
*fieldID = SSMPR_ntohl(*(SSMPRInt32*)curPtr);
|
|
curPtr += sizeof(SSMPRInt32);
|
|
strLen = msg->len - (curPtr - msg->data);
|
|
value->u.string = SSMPORT_ZAlloc(strLen);
|
|
memcpy (value->u.string, curPtr, strLen);
|
|
break;
|
|
default:
|
|
return SSMPR_FAILURE;
|
|
}
|
|
|
|
return SSMPR_SUCCESS;
|
|
}
|
|
|
|
|
|
/* Messages to pickle and unpickle a resource. */
|
|
SSMPRStatus SSM_ParsePickleResourceRequest(void * pickleResourceRequest,
|
|
SSMPRUint32 * resourceID)
|
|
{
|
|
void * curptr = pickleResourceRequest;
|
|
PRStatus rv = PR_SUCCESS;
|
|
|
|
if (!pickleResourceRequest) {
|
|
rv = PR_INVALID_ARGUMENT_ERROR;
|
|
goto loser;
|
|
}
|
|
if (resourceID) *resourceID = SSMPR_ntohl(*(SSMPRUint32 *)curptr);
|
|
|
|
loser:
|
|
if (pickleResourceRequest)
|
|
SSMPORT_Free(pickleResourceRequest);
|
|
return rv;
|
|
}
|
|
|
|
SSMPRInt32 SSM_PackPickleResourceReply(void ** pickleResourceReply,
|
|
SSMPRInt32 result,
|
|
SSMPRUint32 resourceLen,
|
|
void * resource)
|
|
{
|
|
SSMPRInt32 blobSize;
|
|
void * curptr, *tmpStr = NULL;
|
|
PRStatus rv;
|
|
|
|
if (!pickleResourceReply)
|
|
goto loser;
|
|
|
|
*pickleResourceReply = NULL;
|
|
blobSize = sizeof(SSMPRInt32) + sizeof(SSMPRUint32) +
|
|
SSMSTRING_PADDED_LENGTH(resourceLen);
|
|
|
|
/* allocate space for the helloRequest "blob" */
|
|
curptr = (void *)SSMPORT_ZAlloc(blobSize);
|
|
if (!curptr)
|
|
goto loser;
|
|
|
|
*pickleResourceReply = curptr;
|
|
*(SSMPRInt32 *)curptr = SSMPR_htonl(result);
|
|
curptr = (SSMPRInt32 *)curptr + 1;
|
|
|
|
rv = SSM_StringToSSMString((SSMString **)&tmpStr, resourceLen, resource);
|
|
if (rv != SSMPR_SUCCESS)
|
|
goto loser;
|
|
memcpy(curptr, tmpStr, SSM_SIZEOF_STRING(*(SSMString *)tmpStr));
|
|
goto done;
|
|
|
|
loser:
|
|
if (pickleResourceReply && *pickleResourceReply)
|
|
PR_Free(*pickleResourceReply);
|
|
if (tmpStr)
|
|
PR_Free(tmpStr);
|
|
done:
|
|
return blobSize;
|
|
}
|
|
|
|
|
|
SSMPRStatus SSM_ParseUnpickleResourceRequest(void * unpickleResourceRequest,
|
|
SSMPRUint32 blobSize,
|
|
SSMPRUint32 * resourceType,
|
|
SSMPRUint32 * resourceLen,
|
|
void ** resource)
|
|
{
|
|
void * curptr = unpickleResourceRequest;
|
|
SSMPRStatus rv = PR_SUCCESS;
|
|
|
|
if (!unpickleResourceRequest) {
|
|
rv = PR_INVALID_ARGUMENT_ERROR;
|
|
goto loser;
|
|
}
|
|
|
|
if (resourceType)
|
|
*resourceType = PR_ntohl(*(SSMPRUint32 *)curptr);
|
|
curptr = (SSMPRUint32 *)curptr + 1;
|
|
|
|
if (resource) {
|
|
rv = SSM_SSMStringToString((char **)resource, (SSMPRInt32 *)resourceLen,
|
|
(SSMString *)curptr);
|
|
if (rv != SSMPR_SUCCESS)
|
|
goto loser;
|
|
}
|
|
goto done;
|
|
loser:
|
|
if (resource && *resource)
|
|
PR_Free(*resource);
|
|
done:
|
|
if (unpickleResourceRequest)
|
|
PR_Free(unpickleResourceRequest);
|
|
return rv;
|
|
}
|
|
|
|
SSMPRInt32 SSM_PackUnpickleResourceReply(void ** unpickleResourceReply,
|
|
SSMPRInt32 result,
|
|
SSMPRUint32 resourceID)
|
|
{
|
|
SSMPRInt32 blobSize;
|
|
void * curptr;
|
|
|
|
if (!unpickleResourceReply) {
|
|
SSMPORT_SetError(SSMPR_INVALID_ARGUMENT_ERROR);
|
|
return 0;
|
|
}
|
|
*unpickleResourceReply = NULL;
|
|
blobSize = sizeof(SSMPRInt32) + sizeof(SSMPRUint32);
|
|
|
|
/* allocate space for the helloRequest "blob" */
|
|
curptr = (void *)SSMPORT_ZAlloc(blobSize);
|
|
if (!curptr) {
|
|
SSMPORT_SetError(SSMPR_OUT_OF_MEMORY_ERROR);
|
|
return 0;
|
|
}
|
|
*unpickleResourceReply = curptr;
|
|
*(SSMPRInt32 *)curptr = SSMPR_htonl(result);
|
|
curptr = (SSMPRInt32 *)curptr + 1;
|
|
*(SSMPRUint32 *)curptr = SSMPR_htonl(resourceID);
|
|
|
|
return blobSize;
|
|
}
|
|
|
|
/* Destroy resource messages */
|
|
SSMPRStatus SSM_ParseDestroyResourceRequest(void * destroyResourceRequest,
|
|
SSMPRUint32 * resourceID,
|
|
SSMPRUint32 * resourceType)
|
|
{
|
|
void * curptr = destroyResourceRequest;
|
|
PRStatus rv = PR_SUCCESS;
|
|
|
|
if (!destroyResourceRequest) {
|
|
rv = PR_INVALID_ARGUMENT_ERROR;
|
|
goto loser;
|
|
}
|
|
if (resourceID) *resourceID = SSMPR_ntohl(*(SSMPRUint32 *)curptr);
|
|
curptr = (SSMPRUint32 *)curptr + 1;
|
|
if (resourceType) *resourceType = SSMPR_ntohl(*(SSMPRUint32 *)curptr);
|
|
|
|
loser:
|
|
if (destroyResourceRequest)
|
|
SSMPORT_Free(destroyResourceRequest);
|
|
return rv;
|
|
}
|
|
|
|
SSMPRInt32 SSM_PackDestroyResourceReply(void ** destroyResourceReply,
|
|
SSMPRInt32 result)
|
|
{
|
|
return SSM_PackSingleNumReply(destroyResourceReply, result);
|
|
}
|
|
|
|
SSMPRStatus SSM_ParseVerifyCertRequest(void * verifyCertRequest,
|
|
SSMPRUint32 * resourceID,
|
|
SSMPRInt32 * certUsage)
|
|
{
|
|
void * curptr = verifyCertRequest;
|
|
PRStatus rv = PR_SUCCESS;
|
|
|
|
if (!verifyCertRequest) {
|
|
rv = PR_INVALID_ARGUMENT_ERROR;
|
|
goto loser;
|
|
}
|
|
if (resourceID) *resourceID = SSMPR_ntohl(*(SSMPRUint32 *)curptr);
|
|
curptr = (SSMPRUint32 *)curptr + 1;
|
|
if (certUsage) *certUsage = SSMPR_ntohl(*(SSMPRInt32 *)curptr);
|
|
|
|
loser:
|
|
if (verifyCertRequest)
|
|
SSMPORT_Free(verifyCertRequest);
|
|
return rv;
|
|
}
|
|
|
|
SSMPRInt32 SSM_PackVerifyCertReply(void ** verifyCertReply,
|
|
SSMPRInt32 result)
|
|
{
|
|
SSMPRInt32 blobSize;
|
|
void * curptr;
|
|
|
|
if (!verifyCertReply) {
|
|
SSMPORT_SetError(SSMPR_INVALID_ARGUMENT_ERROR);
|
|
return 0;
|
|
}
|
|
*verifyCertReply = NULL;
|
|
blobSize = sizeof(SSMPRInt32);
|
|
/* allocate space for the helloRequest "blob" */
|
|
curptr = (void *)SSMPORT_ZAlloc(blobSize);
|
|
if (!curptr) {
|
|
SSMPORT_SetError(SSMPR_OUT_OF_MEMORY_ERROR);
|
|
return 0;
|
|
}
|
|
*verifyCertReply = curptr;
|
|
*(SSMPRInt32 *)curptr = SSMPR_htonl(result);
|
|
|
|
return blobSize;
|
|
}
|
|
|
|
SSMPRStatus
|
|
SSM_ParseImportCertRequest(void * importCertRequest,
|
|
SSMPRUint32 * blobLen,
|
|
void ** certBlob)
|
|
{
|
|
PRStatus rv;
|
|
void * curptr = importCertRequest;
|
|
PRUint32 length = 0;
|
|
|
|
if (!importCertRequest) {
|
|
rv = PR_INVALID_ARGUMENT_ERROR;
|
|
goto loser;
|
|
}
|
|
|
|
/* in case we fail */
|
|
if (certBlob) *certBlob = NULL;
|
|
if (blobLen)
|
|
*blobLen = 0;
|
|
|
|
if (certBlob) {
|
|
rv = SSM_SSMStringToString((char **)certBlob, (SSMPRInt32 *)&length,
|
|
(SSMString *)curptr);
|
|
if (rv != SSMPR_SUCCESS)
|
|
goto loser;
|
|
}
|
|
if (blobLen)
|
|
*blobLen = length;
|
|
goto done;
|
|
|
|
loser:
|
|
if (certBlob && *certBlob)
|
|
PR_Free(*certBlob);
|
|
done:
|
|
if (importCertRequest)
|
|
SSMPORT_Free(importCertRequest);
|
|
return rv;
|
|
}
|
|
|
|
|
|
SSMPRInt32
|
|
SSM_PackImportCertReply(void ** importCertReply, SSMPRInt32 result,
|
|
SSMPRUint32 resourceID)
|
|
{
|
|
SSMPRInt32 blobSize;
|
|
void * curptr;
|
|
|
|
if (!importCertReply)
|
|
goto loser;
|
|
|
|
*importCertReply = NULL;
|
|
blobSize = sizeof(SSMPRInt32) + sizeof(SSMPRUint32);
|
|
|
|
/* allocate space for the "blob" */
|
|
curptr = (void *)SSMPORT_ZAlloc(blobSize);
|
|
if (!curptr)
|
|
goto loser;
|
|
|
|
*importCertReply = curptr;
|
|
*(SSMPRInt32 *)curptr = SSMPR_htonl(result);
|
|
curptr = (SSMPRInt32 *)curptr + 1;
|
|
*(SSMPRUint32 *)curptr = SSMPR_htonl(resourceID);
|
|
|
|
return blobSize;
|
|
loser:
|
|
if (importCertReply && *importCertReply)
|
|
PR_Free(*importCertReply);
|
|
return 0;
|
|
}
|
|
|
|
PRStatus
|
|
SSM_ParseFindCertByNicknameRequest(void *request, char ** nickname)
|
|
{
|
|
unsigned char * curPtr = request;
|
|
PRStatus rv = PR_SUCCESS;
|
|
|
|
/* Do some basic parameter checking */
|
|
if (!request || !nickname) {
|
|
rv = PR_FAILURE;
|
|
goto loser;
|
|
}
|
|
|
|
/* Get the certificate nickname */
|
|
rv = SSM_SSMStringToString(nickname, NULL, (SSMString*)curPtr);
|
|
if (rv != PR_SUCCESS) {
|
|
goto loser;
|
|
}
|
|
goto done;
|
|
loser:
|
|
done:
|
|
if (request) {
|
|
PR_Free(request);
|
|
}
|
|
return rv;
|
|
}
|
|
|
|
PRInt32
|
|
SSM_PackFindCertByNicknameReply(void ** reply, PRUint32 resourceID)
|
|
{
|
|
unsigned char *curPtr;
|
|
PRInt32 replyLength;
|
|
|
|
/* Do some basic parameter checking */
|
|
if (!reply) {
|
|
goto loser;
|
|
}
|
|
|
|
/* Calculate the message length */
|
|
replyLength = sizeof(PRUint32);
|
|
|
|
curPtr = *reply = PR_Malloc(replyLength);
|
|
if (!curPtr) {
|
|
goto loser;
|
|
}
|
|
|
|
*(PRUint32*)curPtr = PR_htonl(resourceID);
|
|
|
|
return replyLength;
|
|
loser:
|
|
if (reply && *reply) {
|
|
PR_Free(*reply);
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
PRStatus
|
|
SSM_ParseFindCertByKeyRequest(void *request, SECItem ** key)
|
|
{
|
|
unsigned char *curPtr = request;
|
|
PRStatus rv = PR_SUCCESS;
|
|
|
|
/* Do some basic parameter checking */
|
|
if (!request || !key) {
|
|
rv = PR_FAILURE;
|
|
goto loser;
|
|
}
|
|
|
|
/* Allocate the key */
|
|
*key = PR_NEWZAP(SECItem);
|
|
if (!(*key)) {
|
|
goto loser;
|
|
}
|
|
|
|
/* Get the key */
|
|
rv = SSM_SSMStringToString(&((*key)->data), &((*key)->len),
|
|
(SSMString*)curPtr);
|
|
if (rv != PR_SUCCESS) {
|
|
goto loser;
|
|
}
|
|
goto done;
|
|
loser:
|
|
if (*key) {
|
|
if ((*key)->data) {
|
|
PR_Free((*key)->data);
|
|
}
|
|
PR_Free(*key);
|
|
}
|
|
done:
|
|
if (request) {
|
|
PR_Free(request);
|
|
}
|
|
return rv;
|
|
}
|
|
|
|
PRInt32
|
|
SSM_PackFindCertByKeyReply(void ** reply, PRUint32 resourceID)
|
|
{
|
|
unsigned char *curPtr;
|
|
PRInt32 replyLength;
|
|
|
|
/* Do some basic parameter checking */
|
|
if (!reply) {
|
|
goto loser;
|
|
}
|
|
|
|
/* Calculate the message length */
|
|
replyLength = sizeof(PRUint32);
|
|
|
|
curPtr = *reply = PR_Malloc(replyLength);
|
|
if (!curPtr) {
|
|
goto loser;
|
|
}
|
|
|
|
*(PRUint32*)curPtr = PR_htonl(resourceID);
|
|
|
|
return replyLength;
|
|
loser:
|
|
if (reply && *reply) {
|
|
PR_Free(*reply);
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
PRStatus
|
|
SSM_ParseFindCertByEmailAddrRequest(void *request, char ** emailAddr)
|
|
{
|
|
unsigned char * curPtr = request;
|
|
PRStatus rv = PR_SUCCESS;
|
|
|
|
/* Do some basic parameter checking */
|
|
if (!request || !emailAddr) {
|
|
rv = PR_FAILURE;
|
|
goto loser;
|
|
}
|
|
|
|
/* Get the certificate nickname */
|
|
rv = SSM_SSMStringToString(emailAddr, NULL, (SSMString*)curPtr);
|
|
if (rv != PR_SUCCESS) {
|
|
goto loser;
|
|
}
|
|
goto done;
|
|
loser:
|
|
done:
|
|
if (request) {
|
|
PR_Free(request);
|
|
}
|
|
return rv;
|
|
}
|
|
|
|
PRInt32
|
|
SSM_PackFindCertByEmailAddrReply(void ** reply, PRUint32 resourceID)
|
|
{
|
|
unsigned char *curPtr;
|
|
PRInt32 replyLength;
|
|
|
|
/* Do some basic parameter checking */
|
|
if (!reply) {
|
|
goto loser;
|
|
}
|
|
|
|
/* Calculate the message length */
|
|
replyLength = sizeof(PRUint32);
|
|
|
|
curPtr = *reply = PR_Malloc(replyLength);
|
|
if (!curPtr) {
|
|
goto loser;
|
|
}
|
|
|
|
*(PRUint32*)curPtr = PR_htonl(resourceID);
|
|
|
|
return replyLength;
|
|
loser:
|
|
if (reply && *reply) {
|
|
PR_Free(*reply);
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
PRStatus
|
|
SSM_ParseAddTempCertToDBRequest(void *request, PRUint32 *resourceID, char ** nickname, PRInt32 *ssl, PRInt32 *email, PRInt32 *objectSigning)
|
|
{
|
|
unsigned char * curPtr = request;
|
|
PRStatus rv = PR_SUCCESS;
|
|
|
|
/* Do some basic parameter checking */
|
|
if (!request || !resourceID || !nickname) {
|
|
rv = PR_FAILURE;
|
|
goto loser;
|
|
}
|
|
|
|
/* Get the resource ID */
|
|
*resourceID = PR_ntohl(*(PRInt32*)curPtr);
|
|
curPtr += sizeof(PRInt32);
|
|
|
|
/* Get the nickname */
|
|
rv = SSM_SSMStringToString(nickname, NULL, (SSMString*)curPtr);
|
|
if (rv != PR_SUCCESS) {
|
|
goto loser;
|
|
}
|
|
|
|
/* SSL */
|
|
*ssl = PR_ntohl(*(PRInt32*)curPtr);
|
|
curPtr += sizeof(PRInt32);
|
|
|
|
/* Email */
|
|
*email = PR_ntohl(*(PRInt32*)curPtr);
|
|
curPtr += sizeof(PRInt32);
|
|
|
|
/* Object signing */
|
|
*objectSigning = PR_ntohl(*(PRInt32*)curPtr);
|
|
curPtr += sizeof(PRInt32);
|
|
|
|
goto done;
|
|
loser:
|
|
if (nickname && *nickname) {
|
|
PR_Free(*nickname);
|
|
}
|
|
done:
|
|
if (request) {
|
|
PR_Free(request);
|
|
}
|
|
return rv;
|
|
}
|
|
|
|
PRInt32
|
|
SSM_PackAddTempCertToDBReply(void ** reply)
|
|
{
|
|
unsigned char *curPtr;
|
|
PRInt32 replyLength;
|
|
|
|
/* Do some basic parameter checking */
|
|
if (!reply) {
|
|
goto loser;
|
|
}
|
|
|
|
/* Calculate the message length */
|
|
replyLength = sizeof(PRInt32)*3;
|
|
|
|
curPtr = *reply = PR_Malloc(replyLength);
|
|
if (!curPtr) {
|
|
goto loser;
|
|
}
|
|
|
|
return replyLength;
|
|
loser:
|
|
if (reply && *reply) {
|
|
PR_Free(*reply);
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
PRStatus SSM_ParseMatchUserCertRequest(void *request, MatchUserCertRequestData** data)
|
|
{
|
|
MatchUserCertRequestData * requestData;
|
|
char *curPtr = request;
|
|
PRStatus rv = PR_SUCCESS;
|
|
int i;
|
|
|
|
/* Do some basic parameter checking */
|
|
if (!request || !data) {
|
|
rv = PR_FAILURE;
|
|
goto loser;
|
|
}
|
|
|
|
/* Allocate the reply structure */
|
|
requestData = PR_NEWZAP(MatchUserCertRequestData);
|
|
if (NULL == requestData) {
|
|
rv = PR_FAILURE;
|
|
goto loser;
|
|
}
|
|
|
|
/* Get the cert type */
|
|
requestData->certType = PR_ntohl(*(PRUint32*)curPtr);
|
|
curPtr += sizeof(PRUint32);
|
|
|
|
/* Get the number of CAs */
|
|
requestData->numCANames = PR_ntohl(*(PRInt32*)curPtr);
|
|
curPtr += sizeof(PRInt32);
|
|
|
|
/* Get the CA names */
|
|
for (i = 0; i < requestData->numCANames; i++) {
|
|
rv = SSM_SSMStringToString(&(requestData->caNames[i]), NULL, (SSMString*)curPtr);
|
|
if (rv != PR_SUCCESS) {
|
|
goto loser;
|
|
}
|
|
curPtr += SSM_SIZEOF_STRING(*(SSMString*)curPtr);
|
|
}
|
|
|
|
*data = requestData;
|
|
|
|
goto done;
|
|
loser:
|
|
if (requestData) {
|
|
PR_Free(requestData);
|
|
}
|
|
done:
|
|
if (request) {
|
|
PR_Free(request);
|
|
}
|
|
return rv;
|
|
}
|
|
|
|
PRInt32 SSM_PackMatchUserCertReply(void **reply, SSMCertList * certList)
|
|
{
|
|
unsigned char *curPtr;
|
|
PRInt32 replyLength;
|
|
int i;
|
|
SSMCertListElement *head;
|
|
|
|
/* Do some basic parameter checking */
|
|
if (!reply) {
|
|
goto loser;
|
|
}
|
|
|
|
/* Calculate the message length */
|
|
replyLength = sizeof(PRInt32) + (certList->count)*sizeof(PRUint32);
|
|
|
|
curPtr = *reply = PR_Malloc(replyLength);
|
|
if (!curPtr) {
|
|
goto loser;
|
|
}
|
|
|
|
/* Count */
|
|
*((PRInt32*)curPtr) = PR_htonl(certList->count);
|
|
curPtr += sizeof(PRInt32);
|
|
|
|
/* Get the first element */
|
|
head = SSM_CERT_LIST_ELEMENT_PTR(certList->certs.next);
|
|
|
|
for (i = 0; i < certList->count; i++) {
|
|
*((PRUint32*)curPtr) = PR_htonl(head->certResID);
|
|
curPtr += sizeof(PRUint32);
|
|
head = SSM_CERT_LIST_ELEMENT_PTR(head->links.next);
|
|
}
|
|
|
|
return replyLength;
|
|
loser:
|
|
/* XXX Free memory here */
|
|
return 0;
|
|
}
|
|
|
|
SSMPRInt32
|
|
SSM_PackErrorMessage(void ** errorReply, SSMPRInt32 result)
|
|
{
|
|
SSMPRInt32 blobSize;
|
|
|
|
if (!errorReply) {
|
|
SSMPORT_SetError(SSMPR_INVALID_ARGUMENT_ERROR);
|
|
return 0;
|
|
}
|
|
*errorReply = NULL;
|
|
blobSize = sizeof(SSMPRInt32) + sizeof(SSMPRUint32);
|
|
|
|
/* allocate space for the "blob" */
|
|
*errorReply = (void *)SSMPORT_ZAlloc(blobSize);
|
|
if (!*errorReply) {
|
|
SSMPORT_SetError(SSMPR_OUT_OF_MEMORY_ERROR);
|
|
return 0;
|
|
}
|
|
*(SSMPRInt32 *)(*errorReply) = SSMPR_htonl(result);
|
|
return blobSize;
|
|
}
|
|
|
|
SSMPRStatus
|
|
SSM_ParseKeyPairGenRequest(void *keyPairGenRequest, SSMPRInt32 requestLen,
|
|
SSMPRUint32 *keyGenCtxtID,
|
|
SSMPRUint32 *genMechanism,
|
|
SSMPRUint32 *keySize, unsigned char **params,
|
|
SSMPRUint32 *paramLen)
|
|
{
|
|
unsigned char *curPtr = (unsigned char*)keyPairGenRequest;
|
|
SSMPRStatus rv = SSMPR_SUCCESS;
|
|
|
|
if (!keyPairGenRequest) {
|
|
SSMPORT_SetError(SSMPR_INVALID_ARGUMENT_ERROR);
|
|
return SSMPR_FAILURE;
|
|
}
|
|
|
|
/* Now fetch all of the stuff out */
|
|
if (keyGenCtxtID)
|
|
*keyGenCtxtID =SSMPR_ntohl(*((SSMPRInt32*)curPtr));
|
|
curPtr += sizeof(SSMPRInt32);
|
|
|
|
if (genMechanism)
|
|
*genMechanism =SSMPR_ntohl(*((SSMPRInt32*)curPtr));
|
|
curPtr += sizeof(SSMPRInt32);
|
|
|
|
if (keySize)
|
|
*keySize = SSMPR_ntohl(*((SSMPRInt32*)curPtr));
|
|
curPtr += sizeof(SSMPRInt32);
|
|
|
|
rv = SSM_SSMStringToString((char**)params, (int*)paramLen,
|
|
(SSMString*)curPtr);
|
|
return rv;
|
|
}
|
|
|
|
SSMPRInt32
|
|
SSM_PackKeyPairGenResponse(void ** keyPairGenResponse, SSMPRUint32 keyPairId)
|
|
{
|
|
SSMPRInt32 blobSize;
|
|
unsigned char *curPtr;
|
|
|
|
blobSize = sizeof (SSMPRInt32);
|
|
*keyPairGenResponse = curPtr = PORT_ZAlloc(blobSize);
|
|
if (curPtr == NULL) {
|
|
SSMPORT_SetError(SSMPR_OUT_OF_MEMORY_ERROR);
|
|
return 0;
|
|
}
|
|
*((SSMPRInt32*)curPtr) = SSMPR_htonl(keyPairId);
|
|
return blobSize;
|
|
}
|
|
|
|
PRStatus
|
|
SSM_ParseFinishKeyGenRequest(void *finishKeyGenRequest,
|
|
PRInt32 requestLen,
|
|
PRInt32 *keyGenContext)
|
|
{
|
|
if (!finishKeyGenRequest || !keyGenContext) {
|
|
SSMPORT_SetError(SSMPR_INVALID_ARGUMENT_ERROR);
|
|
return PR_FAILURE;
|
|
}
|
|
*keyGenContext = PR_ntohl(*((PRInt32*)finishKeyGenRequest));
|
|
PR_ASSERT(requestLen == sizeof(PRInt32));
|
|
return PR_SUCCESS;
|
|
}
|
|
|
|
SSMPRStatus
|
|
SSM_ParseCreateCRMFReqRequest(void *crmfReqRequest,
|
|
SSMPRInt32 requestLen,
|
|
SSMPRUint32 *keyPairId)
|
|
{
|
|
if (!crmfReqRequest || !keyPairId) {
|
|
SSMPORT_SetError(SSMPR_INVALID_ARGUMENT_ERROR);
|
|
return SSMPR_FAILURE;
|
|
}
|
|
*keyPairId = SSMPR_ntohl(*((SSMPRInt32*)crmfReqRequest));
|
|
return SSMPR_SUCCESS;
|
|
}
|
|
|
|
|
|
SSMPRInt32
|
|
SSM_PackCreateCRMFReqReply(void **crmfReqReply,
|
|
SSMPRUint32 crmfReqId)
|
|
{
|
|
SSMPRInt32 blobSize;
|
|
unsigned char *curPtr;
|
|
|
|
blobSize = sizeof(SSMPRInt32);
|
|
*crmfReqReply = curPtr = (unsigned char *) PORT_ZAlloc(blobSize);
|
|
*((SSMPRInt32*)curPtr) = SSMPR_htonl(crmfReqId);
|
|
return blobSize;
|
|
}
|
|
|
|
SSMPRStatus
|
|
SSM_ParseEncodeCRMFReqRequest(void *encodeReq,
|
|
SSMPRInt32 requestLen,
|
|
SSMPRUint32 **crmfReqIds,
|
|
SSMPRInt32 *numRequests)
|
|
{
|
|
unsigned char *curPtr = (unsigned char*)encodeReq;
|
|
SSMPRInt32 i;
|
|
SSMPRUint32 *reqIdArr;
|
|
if (!encodeReq || !crmfReqIds || !numRequests) {
|
|
SSMPORT_SetError(SSMPR_INVALID_ARGUMENT_ERROR);
|
|
return SSMPR_FAILURE;
|
|
}
|
|
*numRequests = SSMPR_ntohl(*((SSMPRInt32*)encodeReq));
|
|
curPtr += sizeof(SSMPRInt32);
|
|
*crmfReqIds = reqIdArr = SSMPORT_ZNewArray(SSMPRUint32, *numRequests);
|
|
if (reqIdArr == NULL) {
|
|
return SSMPR_FAILURE;
|
|
}
|
|
for (i=0; i<*numRequests;i++) {
|
|
reqIdArr[i] = SSMPR_ntohl(*((SSMPRUint32*)curPtr));
|
|
curPtr += sizeof(SSMPRUint32);
|
|
}
|
|
return SSMPR_SUCCESS;
|
|
}
|
|
|
|
SSMPRInt32
|
|
SSM_PackEncodeCRMFReqReply(void **encodeReply,
|
|
char *crmfDER,
|
|
SSMPRUint32 derLen)
|
|
{
|
|
char *reply;
|
|
SSMPRInt32 blobSize;
|
|
|
|
blobSize = SSMSTRING_PADDED_LENGTH(derLen)+sizeof(SSMPRUint32);
|
|
*encodeReply = reply = (char *) PORT_ZAlloc(blobSize);
|
|
*((SSMPRUint32*)reply) = SSMPR_ntohl(derLen);
|
|
reply += sizeof (SSMPRUint32);
|
|
memcpy(reply, crmfDER, derLen);
|
|
reply += derLen;
|
|
memset(reply, 0 , blobSize - (reply - (*(char**)encodeReply)));
|
|
return blobSize;
|
|
}
|
|
|
|
SSMPRStatus
|
|
SSM_ParseCMMFCertResponse(void *encodedRes,
|
|
SSMPRInt32 encodeLen,
|
|
char **nickname,
|
|
char **base64Der,
|
|
PRBool *doBackup)
|
|
{
|
|
SSMPRStatus rv;
|
|
char *curPtr;
|
|
|
|
if (encodedRes == NULL || nickname == NULL ||
|
|
base64Der == NULL || doBackup == NULL) {
|
|
return SSMPR_FAILURE;
|
|
}
|
|
curPtr = encodedRes;
|
|
PR_ASSERT(*nickname == NULL && *base64Der == NULL);
|
|
*nickname = *base64Der = NULL;
|
|
rv = SSM_SSMStringToString(nickname, NULL, (SSMString*)curPtr);
|
|
if (rv != SSMPR_SUCCESS) {
|
|
goto loser;
|
|
}
|
|
curPtr += SSM_SIZEOF_STRING(*(SSMString*)curPtr);
|
|
rv = SSM_SSMStringToString(base64Der, NULL, (SSMString*)curPtr);
|
|
if (rv != SSMPR_SUCCESS) {
|
|
goto loser;
|
|
}
|
|
curPtr += SSM_SIZEOF_STRING(*(SSMString*)curPtr);
|
|
*doBackup = (SSMPR_ntohl(*(SSMPRUint32*)curPtr) == 0) ? PR_FALSE : PR_TRUE;
|
|
return SSMPR_SUCCESS;
|
|
loser:
|
|
if (nickname && *nickname) {
|
|
PR_Free(*nickname);
|
|
}
|
|
if (base64Der && *base64Der) {
|
|
PR_Free(*base64Der);
|
|
}
|
|
return SSMPR_FAILURE;
|
|
}
|
|
|
|
PRStatus SSM_ParsePOPChallengeRequest(void *challenge,
|
|
PRInt32 len,
|
|
char **responseString)
|
|
{
|
|
if (challenge == NULL || responseString == NULL) {
|
|
return PR_FAILURE;
|
|
}
|
|
*responseString = NULL;
|
|
return SSM_SSMStringToString(responseString, NULL, (SSMString*)challenge);
|
|
|
|
}
|
|
|
|
PRInt32 SSM_PackPOPChallengeResponse(void **response,
|
|
char *responseString,
|
|
PRInt32 responseStringLen)
|
|
{
|
|
PRInt32 blobSize;
|
|
|
|
blobSize = SSMSTRING_PADDED_LENGTH(responseStringLen)+sizeof(PRInt32);
|
|
*response = SSMPORT_ZNewArray(char, blobSize);
|
|
if (SSM_StringToSSMString((SSMString**)response, responseStringLen,
|
|
responseString) != PR_SUCCESS) {
|
|
return 0;
|
|
}
|
|
return blobSize;
|
|
}
|
|
|
|
PRInt32 SSM_PackPasswdRequest(void ** passwdRequest, PRInt32 tokenID,
|
|
char * prompt, PRInt32 promptLen)
|
|
{
|
|
void * curptr, * tmpStr = NULL;
|
|
PRInt32 blobSize;
|
|
PRStatus rv = PR_SUCCESS;
|
|
|
|
if (!passwdRequest || !prompt || tokenID == 0 || promptLen == 0)
|
|
{
|
|
SSMPORT_SetError(SSMPR_INVALID_ARGUMENT_ERROR);
|
|
goto loser;
|
|
}
|
|
*passwdRequest = NULL; /* in case we fail */
|
|
|
|
blobSize = sizeof(PRInt32)*2 + SSMSTRING_PADDED_LENGTH(promptLen);
|
|
curptr = *passwdRequest = PORT_ZAlloc(blobSize);
|
|
if (!*passwdRequest) {
|
|
SSMPORT_SetError(SSMPR_OUT_OF_MEMORY_ERROR);
|
|
goto loser;
|
|
}
|
|
|
|
*(PRInt32 *)curptr = PR_htonl(tokenID);
|
|
curptr = (PRInt32 *)curptr + 1;
|
|
|
|
rv = SSM_StringToSSMString((SSMString **)&tmpStr, promptLen, prompt);
|
|
if (rv != PR_SUCCESS)
|
|
goto loser;
|
|
memcpy(curptr, tmpStr, SSM_SIZEOF_STRING(*(SSMString *)tmpStr));
|
|
goto done;
|
|
|
|
loser:
|
|
if (passwdRequest && *passwdRequest)
|
|
PR_Free(passwdRequest);
|
|
|
|
done:
|
|
if (tmpStr)
|
|
PR_Free(tmpStr);
|
|
return blobSize;
|
|
}
|
|
|
|
PRStatus SSM_ParsePasswordReply(void * passwdReply, PRInt32 * result,
|
|
PRInt32 * tokenID,
|
|
char ** passwd, PRInt32 * passwdLen)
|
|
{
|
|
PRStatus rv = PR_SUCCESS;
|
|
void * curptr = passwdReply;
|
|
|
|
if (!passwdReply) {
|
|
rv = PR_INVALID_ARGUMENT_ERROR;
|
|
goto loser;
|
|
}
|
|
|
|
if (result)
|
|
*result = PR_ntohl(*(PRInt32 *)curptr);
|
|
curptr = (PRInt32 *)curptr + 1;
|
|
|
|
if (tokenID)
|
|
*tokenID = PR_ntohl(*(PRInt32 *)curptr);
|
|
curptr = (PRInt32 *)curptr + 1;
|
|
|
|
if (passwd) {
|
|
*passwd = NULL;
|
|
rv = SSM_SSMStringToString(passwd, passwdLen, (SSMString *)curptr);
|
|
if (rv != PR_SUCCESS && *passwd) {
|
|
PR_Free(*passwd);
|
|
*passwd = NULL;
|
|
passwdLen = 0;
|
|
goto loser;
|
|
}
|
|
}
|
|
goto done;
|
|
loser:
|
|
if (rv == PR_SUCCESS)
|
|
rv = PR_FAILURE;
|
|
if (passwd && *passwd) {
|
|
PR_Free(*passwd);
|
|
*passwd = NULL;
|
|
}
|
|
if (tokenID)
|
|
*tokenID = 0;
|
|
if (passwdLen)
|
|
*passwdLen = 0;
|
|
|
|
done:
|
|
return rv;
|
|
}
|
|
|
|
void SSM_DestroyAttrValue(SSMAttributeValue *value, PRBool freeit)
|
|
{
|
|
if (value->type == SSM_STRING_ATTRIBUTE)
|
|
PR_Free(value->u.string);
|
|
value->type = 0;
|
|
if (freeit)
|
|
PR_Free(value);
|
|
}
|
|
|
|
/* Sign Text functions */
|
|
|
|
PRStatus SSM_ParseSignTextRequest(void* signTextRequest, PRInt32 len, PRUint32* resID, signTextRequestData ** data)
|
|
{
|
|
unsigned char *curPtr = (unsigned char*)signTextRequest;
|
|
signTextRequestData *signTextData = NULL;
|
|
PRStatus rv;
|
|
int i;
|
|
|
|
/* Do some basic parameter checking */
|
|
if (!signTextRequest || !resID || !data) {
|
|
goto loser;
|
|
}
|
|
|
|
/* Allocate the reply structure */
|
|
signTextData = PR_NEWZAP(signTextRequestData);
|
|
if (NULL == signTextData) {
|
|
goto loser;
|
|
}
|
|
|
|
/* Resource ID */
|
|
*resID = PR_ntohl(*(PRInt32*)curPtr);
|
|
curPtr += sizeof(PRInt32);
|
|
|
|
/* String to sign */
|
|
rv = SSM_SSMStringToString(&(signTextData->stringToSign), NULL, (SSMString*)curPtr);
|
|
if (rv != PR_SUCCESS) {
|
|
goto loser;
|
|
}
|
|
curPtr += SSM_SIZEOF_STRING(*(SSMString*)curPtr);
|
|
|
|
/* Host name */
|
|
rv = SSM_SSMStringToString(&(signTextData->hostName), NULL, (SSMString*)curPtr);
|
|
if (rv != PR_SUCCESS) {
|
|
goto loser;
|
|
}
|
|
curPtr += SSM_SIZEOF_STRING(*(SSMString*)curPtr);
|
|
|
|
/* CA option */
|
|
rv = SSM_SSMStringToString(&(signTextData->caOption), NULL, (SSMString*)curPtr);
|
|
if (rv != PR_SUCCESS) {
|
|
goto loser;
|
|
}
|
|
curPtr += SSM_SIZEOF_STRING(*(SSMString*)curPtr);
|
|
|
|
/* Number of CAs */
|
|
signTextData->numCAs = PR_ntohl(*(PRInt32*)curPtr);
|
|
curPtr += sizeof(PRInt32);
|
|
|
|
signTextData->caNames = PR_Malloc(sizeof(char*)*(signTextData->numCAs));
|
|
|
|
for (i = 0; i < signTextData->numCAs; i++) {
|
|
rv = SSM_SSMStringToString(&(signTextData->caNames[i]), NULL, (SSMString*)curPtr);
|
|
if (rv != PR_SUCCESS) {
|
|
goto loser;
|
|
}
|
|
curPtr += SSM_SIZEOF_STRING(*(SSMString*)curPtr);
|
|
}
|
|
|
|
*data = signTextData;
|
|
|
|
/* Free the incoming data buffer */
|
|
PR_Free(signTextRequest);
|
|
|
|
return PR_SUCCESS;
|
|
loser:
|
|
if (signTextData) {
|
|
if (signTextData->stringToSign) {
|
|
PR_Free(signTextData->stringToSign);
|
|
}
|
|
if (signTextData->hostName) {
|
|
PR_Free(signTextData->hostName);
|
|
}
|
|
if (signTextData->numCAs) {
|
|
/* XXX Free the CA Names */
|
|
}
|
|
PR_Free(signTextData);
|
|
}
|
|
return PR_FAILURE;
|
|
}
|
|
|
|
PRStatus SSM_ParseGetLocalizedTextRequest(void *data,
|
|
SSMLocalizedString *whichString)
|
|
{
|
|
return SSM_ParseSingleNumRequest(data, (SSMPRUint32*)whichString);
|
|
}
|
|
|
|
PRInt32 SSM_PackGetLocalizedTextResponse(void **data,
|
|
SSMLocalizedString whichString,
|
|
char *retString)
|
|
{
|
|
char *tmpPtr;
|
|
PRInt32 replyLen;
|
|
int retStrLen;
|
|
|
|
retStrLen = strlen(retString);
|
|
replyLen = SSMSTRING_PADDED_LENGTH(retStrLen)+(2*sizeof(PRInt32));
|
|
|
|
tmpPtr = SSMPORT_ZNewArray(char, replyLen);
|
|
if (tmpPtr == NULL) {
|
|
*data = NULL;
|
|
return 0;
|
|
}
|
|
*data = tmpPtr;
|
|
*(PRUint32*)tmpPtr = PR_htonl(whichString);
|
|
tmpPtr += sizeof(PRUint32);
|
|
*(PRUint32*)tmpPtr = PR_htonl(retStrLen);
|
|
tmpPtr += sizeof(PRUint32);
|
|
memcpy(tmpPtr, retString, retStrLen);
|
|
return replyLen;
|
|
}
|
|
|
|
PRStatus SSM_ParseAddNewSecurityModuleRequest(void *data,
|
|
char **moduleName,
|
|
char **libraryPath,
|
|
unsigned long *pubMechFlags,
|
|
unsigned long *pubCipherFlags)
|
|
{
|
|
char *tmpPtr;
|
|
PRStatus rv;
|
|
|
|
if (data == NULL) {
|
|
return PR_FAILURE;
|
|
}
|
|
if (moduleName != NULL) {
|
|
*moduleName = NULL;
|
|
}
|
|
if (libraryPath != NULL) {
|
|
*libraryPath = NULL;
|
|
}
|
|
tmpPtr = data;
|
|
if (moduleName) {
|
|
rv = SSM_SSMStringToString(moduleName, NULL, (SSMString*)tmpPtr);
|
|
if (rv != PR_SUCCESS) {
|
|
goto loser;
|
|
}
|
|
}
|
|
tmpPtr += SSM_SIZEOF_STRING(*(SSMString*)tmpPtr);
|
|
if (libraryPath) {
|
|
rv =SSM_SSMStringToString(libraryPath, NULL, (SSMString*)tmpPtr);
|
|
if (rv != PR_SUCCESS) {
|
|
goto loser;
|
|
}
|
|
}
|
|
tmpPtr += SSM_SIZEOF_STRING(*(SSMString*)tmpPtr);
|
|
*pubMechFlags = PR_ntohl(*(unsigned long*)tmpPtr);
|
|
tmpPtr += sizeof(unsigned long);
|
|
*pubCipherFlags = PR_ntohl(*(unsigned long*)tmpPtr);
|
|
return PR_SUCCESS;
|
|
loser:
|
|
if (moduleName && *moduleName) {
|
|
PR_Free(moduleName);
|
|
}
|
|
if (libraryPath && *libraryPath) {
|
|
PR_Free(libraryPath);
|
|
}
|
|
return PR_FAILURE;
|
|
}
|
|
|
|
PRInt32 SSM_PackAddNewModuleResponse(void **data, PRInt32 rv)
|
|
{
|
|
return SSM_PackSingleNumReply(data, rv);
|
|
}
|
|
|
|
PRStatus SSM_ParseDeleteSecurityModuleRequest(void *data, char **moduleName)
|
|
{
|
|
PRStatus rv = PR_FAILURE;
|
|
|
|
if (data == NULL) {
|
|
goto done;
|
|
}
|
|
if (moduleName) {
|
|
*moduleName = NULL;
|
|
rv = SSM_SSMStringToString(moduleName, NULL, (SSMString*)data);
|
|
}
|
|
done:
|
|
return rv;
|
|
}
|
|
|
|
PRInt32 SSM_PackDeleteModuleResponse(void **data, PRInt32 moduleType)
|
|
{
|
|
return SSM_PackSingleNumReply(data, moduleType);
|
|
}
|
|
|
|
/* messages for importing certs *the traditional way* */
|
|
PRInt32 SSM_PackDecodeCertReply(void ** data, PRInt32 certID)
|
|
{
|
|
return SSM_PackSingleNumReply(data, certID);
|
|
}
|
|
|
|
PRStatus SSM_ParseDecodeCertRequest(void * data, PRInt32 * len,
|
|
char ** buffer)
|
|
{
|
|
if (!data)
|
|
goto loser;
|
|
|
|
if (buffer) {
|
|
return SSM_SSMStringToString(buffer, len, (SSMString*)data);
|
|
}
|
|
loser:
|
|
return PR_FAILURE;
|
|
}
|
|
|
|
PRStatus SSM_ParseDecodeAndCreateTempCertRequest(void * data,
|
|
char ** certbuf, PRUint32 * certlen, int * certClass)
|
|
{
|
|
PRStatus rv = PR_FAILURE;
|
|
|
|
if (!data)
|
|
goto loser;
|
|
|
|
*certClass = PR_ntohl(*(int *)data);
|
|
rv = SSM_SSMStringToString(certbuf, certlen, (SSMString *)((char *)data + sizeof(int)));
|
|
if (rv != PR_SUCCESS)
|
|
goto loser;
|
|
|
|
loser:
|
|
if (data)
|
|
PR_Free(data);
|
|
return rv;
|
|
}
|
|
|
|
|
|
PRStatus SSM_ParseGetKeyChoiceListRequest(void * data, PRUint32 dataLen,
|
|
char ** type, PRUint32 *typeLen,
|
|
char ** pqgString, PRUint32 * pqgLen)
|
|
{
|
|
PRStatus rv = PR_SUCCESS;
|
|
void * curptr = data;
|
|
char * field = NULL, * value;
|
|
PRUint32 len;
|
|
|
|
/* in fact, this is perfectly OK, loser is just an exit tag */
|
|
if (!data)
|
|
goto loser;
|
|
|
|
if (type) *type = NULL;
|
|
if (pqgString) *pqgString = NULL;
|
|
|
|
while ((long)curptr < (long)data + dataLen) {
|
|
rv = SSM_SSMStringToString(&field, &len, (SSMString *)curptr);
|
|
if (rv != PR_SUCCESS)
|
|
goto loser;
|
|
curptr = (char *)curptr + SSMSTRING_PADDED_LENGTH(len) + sizeof(PRInt32);
|
|
rv = SSM_SSMStringToString(&value, &len, (SSMString *)curptr);
|
|
if (rv != PR_SUCCESS)
|
|
goto loser;
|
|
curptr = (char *)curptr + SSMSTRING_PADDED_LENGTH(len) + sizeof(PRInt32);
|
|
|
|
if (type && PORT_Strcmp(field, "type")==0) {
|
|
*type = value;
|
|
if (typeLen) *typeLen = len;
|
|
} else if (pqgString && PORT_Strcmp(field, "pqg")==0) {
|
|
*pqgString = value;
|
|
if (pqgLen) *pqgLen = len;
|
|
}
|
|
if (field) PR_Free(field);
|
|
}
|
|
|
|
loser:
|
|
if (data)
|
|
PR_Free(data);
|
|
return rv;
|
|
}
|
|
|
|
|
|
PRInt32 SSM_PackGetKeyChoiceListReply(void ** data, char ** list)
|
|
{
|
|
PRInt32 len = 0, i=0, oldlen;
|
|
char * tmpString = NULL, * tmp = NULL;
|
|
PRStatus rv = PR_FAILURE;
|
|
|
|
*data = NULL;
|
|
|
|
while (list[i] != 0) {
|
|
oldlen = len;
|
|
len = len + SSMSTRING_PADDED_LENGTH(strlen(list[i])) + sizeof(PRInt32);
|
|
if (tmp)
|
|
tmp = PR_REALLOC(tmp, len);
|
|
else
|
|
tmp = PORT_ZAlloc(len);
|
|
if (!tmp)
|
|
goto loser;
|
|
rv = SSM_StringToSSMString((SSMString **)&tmpString, 0, list[i]);
|
|
if (rv != PR_SUCCESS)
|
|
goto loser;
|
|
memcpy(tmp+oldlen, tmpString, len-oldlen);
|
|
i++;
|
|
}
|
|
|
|
*data = PORT_ZAlloc(len + sizeof(i));
|
|
oldlen = PR_htonl(i);
|
|
*(PRInt32 *)*data = oldlen; /* number of strings */
|
|
memcpy((char *)*data + sizeof(i), tmp, len);
|
|
|
|
return len+sizeof(i);
|
|
|
|
loser:
|
|
/* scream out loud, should not be breaking here
|
|
SSM_DEBUG("Error in packGetKeyChoiceListReply!\n");
|
|
*/
|
|
*data = NULL;
|
|
return 0;
|
|
}
|
|
|
|
|
|
PRStatus SSM_ParseGenKeyOldStyleRequest(void * data, PRUint32 datalen,
|
|
char ** choiceString,
|
|
char ** challenge,
|
|
char ** typeString,
|
|
char ** pqgString)
|
|
{
|
|
char * curptr = (char *)data;
|
|
PRStatus rv;
|
|
|
|
if (!data)
|
|
goto loser;
|
|
|
|
if (choiceString) {
|
|
rv = SSM_SSMStringToString(choiceString, NULL, (SSMString *)curptr);
|
|
if (rv != PR_SUCCESS)
|
|
goto loser;
|
|
}
|
|
curptr = (char *)curptr + SSM_SIZEOF_STRING(*(SSMString *)curptr);
|
|
|
|
if (challenge) {
|
|
rv = SSM_SSMStringToString(challenge, NULL, (SSMString *)curptr);
|
|
if (rv != PR_SUCCESS)
|
|
goto loser;
|
|
}
|
|
curptr = (char *)curptr + SSM_SIZEOF_STRING(*(SSMString *)curptr);
|
|
|
|
if (typeString) {
|
|
rv = SSM_SSMStringToString(typeString, NULL, (SSMString *)curptr);
|
|
if (rv != PR_SUCCESS)
|
|
goto loser;
|
|
}
|
|
curptr = (char *)curptr + SSM_SIZEOF_STRING(*(SSMString *)curptr);
|
|
|
|
if (pqgString) {
|
|
rv = SSM_SSMStringToString(pqgString, NULL, (SSMString *)curptr);
|
|
if (rv != PR_SUCCESS)
|
|
goto loser;
|
|
}
|
|
curptr = (char *)curptr + SSM_SIZEOF_STRING(*(SSMString *)curptr);
|
|
goto done;
|
|
|
|
loser:
|
|
if (pqgString && *pqgString) {
|
|
PR_Free(*pqgString);
|
|
*pqgString = NULL;
|
|
}
|
|
if (typeString && *typeString) {
|
|
PR_Free(*typeString);
|
|
*typeString = NULL;
|
|
}
|
|
if (challenge && *challenge) {
|
|
PR_Free(*challenge);
|
|
*challenge = NULL;
|
|
}
|
|
if (choiceString && *choiceString) {
|
|
PR_Free(*choiceString);
|
|
*choiceString = NULL;
|
|
}
|
|
if (rv == PR_SUCCESS)
|
|
rv = PR_FAILURE;
|
|
done:
|
|
if (data)
|
|
PR_Free(data);
|
|
return rv;
|
|
}
|
|
|
|
|
|
PRInt32 SSM_PackGenKeyOldStyleReply(void ** data, char * keydata)
|
|
{
|
|
PRStatus rv;
|
|
char * curptr;
|
|
|
|
if (!data)
|
|
return 0;
|
|
|
|
rv = SSM_StringToSSMString((SSMString **)&curptr, 0, keydata);
|
|
if (rv != PR_SUCCESS)
|
|
return 0;
|
|
|
|
*data = curptr;
|
|
return SSM_SIZEOF_STRING(*(SSMString *)curptr);
|
|
}
|
|
|
|
|
|
PRInt32 SSM_PackFilePathRequest(void **data, PRInt32 resID, char *prompt,
|
|
PRBool shouldFileExist, char *fileSuffix)
|
|
{
|
|
PRInt32 reqLen;
|
|
char *request;
|
|
PRInt32 promptLen, fileSufLen;
|
|
|
|
promptLen = strlen(prompt);
|
|
fileSufLen = strlen(fileSuffix);
|
|
reqLen = SSMSTRING_PADDED_LENGTH(promptLen) +
|
|
SSMSTRING_PADDED_LENGTH(fileSufLen) + (4*sizeof(PRInt32));
|
|
request = SSMPORT_ZNewArray(char, reqLen);
|
|
if (request == NULL) {
|
|
*data = NULL;
|
|
return 0;
|
|
}
|
|
*data = request;
|
|
*(PRInt32*)request = PR_htonl(resID);
|
|
request += sizeof(PRInt32);
|
|
*(PRInt32*)request = PR_htonl(shouldFileExist);
|
|
request += sizeof(PRInt32);
|
|
*(PRInt32*)request = PR_htonl(promptLen);
|
|
request += sizeof(PRInt32);
|
|
memcpy(request, prompt, promptLen);
|
|
request += SSMSTRING_PADDED_LENGTH(promptLen);
|
|
*(PRInt32*)request = PR_htonl(fileSufLen);
|
|
request += sizeof(PRInt32);
|
|
memcpy(request, fileSuffix, fileSufLen);
|
|
return reqLen;
|
|
}
|
|
|
|
PRStatus SSM_ParseFilePathReply(void *message, char **filePath,
|
|
PRInt32 *rid)
|
|
{
|
|
unsigned char *curPtr = message;
|
|
|
|
*rid = PR_ntohl(*(PRInt32*)curPtr);
|
|
curPtr += sizeof(PRInt32);
|
|
if (filePath != NULL) {
|
|
*filePath = NULL;
|
|
SSM_SSMStringToString(filePath, NULL, (SSMString*)curPtr);
|
|
}
|
|
curPtr += SSM_SIZEOF_STRING(*(SSMString*)curPtr);
|
|
return PR_SUCCESS;
|
|
}
|
|
|
|
PRInt32 SSM_PackPromptRequestEvent(void **data, PRInt32 resID, char *prompt)
|
|
{
|
|
PRInt32 promptLen;
|
|
PRInt32 reqLen;
|
|
char *request;
|
|
|
|
promptLen = strlen(prompt);
|
|
reqLen = SSMSTRING_PADDED_LENGTH(promptLen) + (2*sizeof(PRInt32));
|
|
*data = request = SSMPORT_ZNewArray(char, reqLen);
|
|
if (request == NULL) {
|
|
*data = NULL;
|
|
return 0;
|
|
}
|
|
*(PRInt32*)request = PR_htonl(resID);
|
|
request += sizeof(PRInt32);
|
|
*(PRInt32*)request = PR_htonl(promptLen);
|
|
request += sizeof(PRInt32);
|
|
memcpy(request, prompt, promptLen);
|
|
return reqLen;
|
|
}
|
|
|
|
PRStatus
|
|
SSM_ParsePasswordPromptReply(void *data, PRInt32 *resID, char **reply)
|
|
{
|
|
/* The Message formats are the same, so I can do this. */
|
|
return SSM_ParseFilePathReply(data, reply, resID);
|
|
}
|