⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 sslskst.c

📁 安全开发库。含客户端建立ssl连接、签名、证书验证、证书发布和撤销等。编译用到nss
💻 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. */#include "sslconn.h"#include "ctrlconn.h"#include "serv.h"#include "servimpl.h"/* Shorthand macros for inherited classes */#define SSMRESOURCE(ss) (&(ss)->super)/* implemented in resource.c: this should belong to resource.h! */SSMStatus SSM_UnpickleResource(SSMResource** res, SSMResourceType type,                               SSMControlConnection* connection,                              PRIntn len, void* value);SSMStatusSSMSSLSocketStatus_Create(void *arg, SSMControlConnection * connection,                           SSMResource **res){    SSMStatus rv = PR_SUCCESS;    SSMSSLSocketStatus *ss;    *res = NULL; /* in case we fail */        ss = (SSMSSLSocketStatus *) PR_CALLOC(sizeof(SSMSSLSocketStatus));    if (!ss) goto loser;    rv = SSMSSLSocketStatus_Init(ss, connection, 				 (PRFileDesc *) arg,                                  SSM_RESTYPE_SSL_SOCKET_STATUS);    if (rv != PR_SUCCESS) goto loser;    SSMSSLSocketStatus_Invariant(ss);    *res = &ss->super;    return PR_SUCCESS; loser:    if (rv == PR_SUCCESS) rv = PR_FAILURE;    if (ss)     {        SSMRESOURCE(ss)->m_refCount = 1; /* force destroy */        SSM_FreeResource(SSMRESOURCE(ss));    }            return rv;}SSMStatus SSMSSLSocketStatus_Init(SSMSSLSocketStatus *ss,  			SSMControlConnection * connection,                         PRFileDesc *fd, SSMResourceType type){    SSMStatus rv = PR_SUCCESS;    int keySize, secretKeySize, level;    SSMResource *certObj;    SSMResourceID certRID;    /* Initialize superclass */    SSMResource_Init(connection, SSMRESOURCE(ss), type);    /* Get the peer cert and import it into a PSM object */    ss->m_cert = SSL_PeerCertificate(fd);    if (!ss->m_cert) goto loser;    rv = SSM_CreateResource(SSM_RESTYPE_CERTIFICATE, ss->m_cert,                             SSMRESOURCE(ss)->m_connection, &certRID,                             &certObj);     if (rv != PR_SUCCESS) goto loser;    ss->m_certID = certObj->m_id;    /* Get the other socket status information */    rv = SSL_SecurityStatus(fd, &level, &ss->m_cipherName,                            &keySize,                            &secretKeySize,                            NULL, NULL);    if (rv != PR_SUCCESS) goto loser;    ss->m_keySize = keySize;    ss->m_secretKeySize = secretKeySize;    ss->m_level = level;    /* Sanity check before returning */    SSMSSLSocketStatus_Invariant(ss);        goto done;loser:    /* member destruct, if any are allocated, will happen in the       _Destroy method */    if (rv == PR_SUCCESS) rv = PR_FAILURE;done:    return rv;}SSMStatus SSMSSLSocketStatus_Destroy(SSMResource *res, PRBool doFree){    SSMSSLSocketStatus *ss = (SSMSSLSocketStatus *) res;    SSMSSLSocketStatus_Invariant(ss);    /* Destroy our members. */    if (ss->m_cert)    {        CERT_DestroyCertificate(ss->m_cert);        ss->m_cert = NULL;    }    if (ss->m_cipherName)    {        PORT_Free(ss->m_cipherName);        ss->m_cipherName = NULL;    }    /* Destroy superclass. */    SSMResource_Destroy(res, PR_FALSE);        /* Free if asked. */    if (doFree)        PR_Free(res);    return PR_SUCCESS;}void SSMSSLSocketStatus_Invariant(SSMSSLSocketStatus *ss){    /* Superclass invariant */    SSMResource_Invariant(SSMRESOURCE(ss));        /* Class check */    PR_ASSERT(SSM_IsAKindOf(SSMRESOURCE(ss), SSM_RESTYPE_SSL_SOCKET_STATUS));    /* Member check */    /* Make sure we used a cert to initialize ourselves */    if (ss->m_certID)        PR_ASSERT(ss->m_cert != NULL);}SSMStatus SSMSSLSocketStatus_GetAttrIDs(SSMResource *res,                              SSMAttributeID **ids,                              PRIntn *count){    SSMStatus rv;    rv = SSMResource_GetAttrIDs(res, ids, count);    if (rv != PR_SUCCESS)        goto loser;    *ids = (SSMAttributeID *) PR_REALLOC(*ids, (*count + 4) * sizeof(SSMAttributeID));    if (! *ids) goto loser;    (*ids)[*count++] = SSM_FID_SSS_KEYSIZE;    (*ids)[*count++] = SSM_FID_SSS_SECRET_KEYSIZE;    (*ids)[*count++] = SSM_FID_SSS_CERT_ID;    (*ids)[*count++] = SSM_FID_SSS_CIPHER_NAME;    goto done; loser:    if (rv == PR_SUCCESS) rv = PR_FAILURE; done:    return rv;}SSMStatus SSMSSLSocketStatus_GetAttr(SSMResource *res,                           SSMAttributeID attrID,                           SSMResourceAttrType attrType,                           SSMAttributeValue *value){    SSMStatus rv = PR_SUCCESS;    SSMSSLSocketStatus *ss = (SSMSSLSocketStatus *) res;    char *tmpstr = NULL;    SSM_DEBUG("socket status get attr is called.\n");    SSMSSLSocketStatus_Invariant(ss);    /* see what it is */    switch(attrID)    {    case SSM_FID_SSS_KEYSIZE:         value->type = SSM_NUMERIC_ATTRIBUTE;        value->u.numeric = ss->m_keySize;        break;    case SSM_FID_SSS_SECRET_KEYSIZE:        value->type = SSM_NUMERIC_ATTRIBUTE;        value->u.numeric = ss->m_secretKeySize;        break;    case SSM_FID_SSS_CERT_ID:        value->type = SSM_RID_ATTRIBUTE;        value->u.numeric = ss->m_certID;        break;    case SSM_FID_SSS_SECURITY_LEVEL:        value->type = SSM_NUMERIC_ATTRIBUTE;        value->u.numeric = ss->m_level;        break;    case SSM_FID_SSS_CIPHER_NAME:        value->type = SSM_STRING_ATTRIBUTE;        value->u.string.len = PL_strlen(ss->m_cipherName);        value->u.string.data = (unsigned char *) PL_strdup(ss->m_cipherName);        break;    case SSM_FID_SSS_HTML_STATUS:        value->type = SSM_STRING_ATTRIBUTE;        rv = (*res->m_html_func)(res, NULL, (void**)&tmpstr);        value->u.string.len = PL_strlen(tmpstr);        value->u.string.data = (unsigned char *) PL_strdup(tmpstr);        break;    default:        rv = SSMResource_GetAttr(res,attrID,attrType,value);        if (rv != PR_SUCCESS)            goto loser;    }    goto done; loser:    value->type = SSM_NO_ATTRIBUTE;    if (rv == PR_SUCCESS) rv = PR_FAILURE; done:    if (tmpstr != NULL)        PR_Free(tmpstr);    return rv;}SSMStatus SSMSSLSocketStatus_Pickle(SSMResource *res, PRIntn * len,                                   void **value){     int blobSize, certSize;    SSMStatus rv;    SSMSSLSocketStatus * resource = (SSMSSLSocketStatus *)res;    SSMResourceCert *certObj;    void * certBlob, *curptr, *tmpStr = NULL;    if (!res || !value) {        rv = PR_INVALID_ARGUMENT_ERROR;        goto loser;    }    /* in case we fail */    *value = NULL;    if (len) *len = 0;        /* first, pickle cert */    rv = SSMControlConnection_GetResource(res->m_connection,                                           resource->m_certID,                                          (SSMResource **)&certObj);    if (rv != PR_SUCCESS) goto loser;        rv = SSM_PickleResource(SSMRESOURCE(certObj), &certSize, &certBlob);     if (rv != PR_SUCCESS)         goto loser;        /* allocate memory for the pickled blob */    blobSize = certSize + sizeof(PRUint32)*5 +         SSMSTRING_PADDED_LENGTH(strlen(resource->m_cipherName));    curptr = PORT_ZAlloc(blobSize);    if (!curptr) {        rv = PR_OUT_OF_MEMORY_ERROR;        goto loser;    }    *value = curptr;    *(PRUint32 *)curptr = resource->m_keySize;    curptr = (PRUint32 *)curptr + 1;    *(PRUint32 *)curptr = resource->m_secretKeySize;    curptr = (PRUint32 *)curptr + 1;	*(PRInt32*)curptr = resource->m_level;	curptr = (PRInt32 *)curptr + 1;	*(PRInt32*)curptr = resource->m_error;	curptr = (PRInt32 *)curptr + 1;	rv = SSM_StringToSSMString((SSMString **)&tmpStr, 0, resource->m_cipherName);    if (rv != PR_SUCCESS)         goto loser;    memcpy(curptr, tmpStr, SSM_SIZEOF_STRING(*(SSMString *)tmpStr));    curptr = (char *)curptr + SSM_SIZEOF_STRING(*(SSMString *)tmpStr);    PR_Free(tmpStr);    tmpStr = NULL;    /* copy cert into the blob */    memcpy(curptr, certBlob, certSize);    if (len) *len = blobSize;            return rv;    loser:    if (rv == PR_SUCCESS)        rv = PR_FAILURE;    if (value && *value)        PR_Free(*value);    if (len)         *len = 0;    if (tmpStr)         PR_Free(tmpStr);    return rv;}SSMStatus SSMSSLSocketStatus_Unpickle(SSMResource ** res,                                      SSMControlConnection * connection,                                      PRInt32 len,                                      void *value){    SSMStatus rv = PR_SUCCESS;    SSMSSLSocketStatus *ss;    void * curptr = NULL;    PRUint32 strLength = 0, certLength = 0;    SSMResource * certResource = NULL;    if (!res || !value) {        rv = PR_INVALID_ARGUMENT_ERROR;        goto loser;    }    *res = NULL; /* in case we fail */        ss = (SSMSSLSocketStatus *) PR_CALLOC(sizeof(SSMSSLSocketStatus));    if (!ss) goto loser;    ss->m_cipherName = NULL;    ss->m_certID = 0;    /* Initialize superclass */    SSMResource_Init(connection, SSMRESOURCE(ss), 		     SSM_RESTYPE_SSL_SOCKET_STATUS);    /* Unpickle socket status data */    curptr = value;        ss->m_keySize = *(PRUint32 *)curptr;    curptr =(PRUint32 *)curptr + 1;      ss->m_secretKeySize = *(PRUint32 *)curptr;    curptr =(PRUint32 *)curptr + 1;     ss->m_level = *(PRInt32 *)curptr;	curptr = (PRInt32 *)curptr + 1;	ss->m_error = *(PRInt32 *)curptr;	curptr = (PRInt32 *)curptr + 1;    /* Fix this */    rv = SSM_SSMStringToString(&ss->m_cipherName, (int *) &strLength,                                (SSMString *)curptr);    if (rv != PR_SUCCESS || ss->m_cipherName == NULL || strLength == 0)         goto loser;    curptr = (char *)curptr + SSMSTRING_PADDED_LENGTH(strLength) +         sizeof(PRUint32);        /* Unpickle cert */    certLength = len - ((unsigned long)curptr - (unsigned long)value);    rv = SSM_UnpickleResource(&certResource, SSM_RESTYPE_CERTIFICATE,                               connection, certLength, curptr);    if (rv != PR_SUCCESS || !certResource)        goto loser;    ss->m_certID = certResource->m_id;    ss->m_cert = ((SSMResourceCert *)certResource)->cert;     /* Sanity check before returning */    SSMSSLSocketStatus_Invariant(ss);        *res = SSMRESOURCE(ss);    goto done;    loser:    if (ss) {        if (ss->m_cipherName)            PR_Free(ss->m_cipherName);        if (ss->m_certID && certResource)             (*(certResource->m_destroy_func))(certResource, PR_TRUE);        PR_Free(certResource);    }    if (rv == PR_SUCCESS)         rv = PR_FAILURE;done:     return rv;}SSMStatus SSMSSLSocketStatus_HTML(SSMResource *res, PRIntn *len, void ** value){     SSMStatus rv = PR_SUCCESS;    SSMSSLSocketStatus * resource = (SSMSSLSocketStatus *)res;    char * line = NULL;     if (!res || !value) {        rv = PR_INVALID_ARGUMENT_ERROR;        goto loser;    }    if (len) *len = 0;    *value = NULL;        switch (resource->m_level) {    case SSL_SECURITY_STATUS_ON_HIGH:#ifdef FORTEZZA    case SSL_SECURITY_STATUS_FORTEZZA:#endif        line = PR_smprintf("%s", SECURITY_HIGH_MESSAGE);        break;      case SSL_SECURITY_STATUS_ON_LOW:        line = PR_smprintf("%s", SECURITY_LOW_MESSAGE);        break;    default:        *value = PR_smprintf("%s", SECURITY_NO_MESSAGE);        goto done;    }     if (resource->m_keySize != resource->m_secretKeySize) {        *value = PR_smprintf("%s (%s, %d bit with %d secret).", line,                             resource->m_cipherName,                              resource->m_keySize,                              resource->m_secretKeySize);    } else {        *value = PR_smprintf("%s (%s, %d bit).", line,                              resource->m_cipherName,                             resource->m_keySize);    }        goto done;loser:    if (value && *value)        PR_Free(*value);    *value = NULL;    if (len && *len)        *len = 0;    if (rv == PR_SUCCESS)         rv = PR_FAILURE;done:    if (value && *value && len)         *len = strlen((char *)*value)+1;    if (line)         PR_Free(line);    return rv;}SSMStatus SSMSSLSocketStatus_UpdateSecurityStatus(SSMSSLSocketStatus* ss,                                                 PRFileDesc* socket){    SSMStatus rv = PR_SUCCESS;    int keySize, secretKeySize, level;    /* ss should not be NULL when this function is called */    PR_ASSERT(ss != NULL);    /* Get the security status information */    if (ss->m_cipherName != NULL) {        PR_Free(ss->m_cipherName);        ss->m_cipherName = NULL;    }    rv = SSL_SecurityStatus(socket, &level, &ss->m_cipherName, &keySize,                             &secretKeySize, NULL, NULL);    if (rv != PR_SUCCESS) {        goto loser;    }    ss->m_keySize = keySize;    ss->m_secretKeySize = secretKeySize;    ss->m_level = level;    /* Sanity check before returning */    SSMSSLSocketStatus_Invariant(ss);        goto done;loser:    if (rv == PR_SUCCESS) {        rv = PR_FAILURE;    }    if (ss->m_cipherName != NULL) {        PR_Free(ss->m_cipherName);        ss->m_cipherName = NULL;    }done:    return rv;}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -