📄 protocolf.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) {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -