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

📄 crmfres.c

📁 安全开发库。含客户端建立ssl连接、签名、证书验证、证书发布和撤销等。编译用到nss
💻 C
📖 第 1 页 / 共 3 页
字号:
  CMMFCertResponse   *currResponse   = NULL;  PK11SlotInfo       *slot           = NULL;  CERTCertificate   **certArr        = NULL;  CMMFPKIStatus       reqStatus;  PRBool              isPerm;  CMMFCertResponseRequest request;  if (CMT_DecodeMessage(CMMFCertResponseRequestTemplate, &request,                         (CMTItem*)msg) != CMTSuccess) {      goto loser;  }  srv = ATOB_ConvertAsciiToItem(&cmmfDer, request.base64Der);  if (srv != SECSuccess || cmmfDer.data == NULL) {      goto loser;  }  certRepContent = CMMF_CreateCertRepContentFromDER(connection->m_certdb,                                                    (const char*)cmmfDer.data,                                                    cmmfDer.len);  if (certRepContent == NULL) {      /* This could be a key recovery response, but fail for now. */      goto loser;  }  numResponses = CMMF_CertRepContentGetNumResponses(certRepContent);  if (request.doBackup) {      certArr = SSM_ZNEW_ARRAY(CERTCertificate*, numResponses);      if (certArr == NULL) {          /* Let's not do back up in this case. */          request.doBackup = (CMBool) PR_FALSE;      }  }  for (i=0; i<numResponses; i++) {      currResponse = CMMF_CertRepContentGetResponseAtIndex(certRepContent, i);      if (currResponse == NULL) {          goto loser;      }      /* Need to make sure the ID corresponds to a request PSM actually       * made.  Figure out how you're gonna do this.       */      reqStatus = CMMF_CertResponseGetPKIStatusInfoStatus(currResponse);      if (!(reqStatus == cmmfGranted || reqStatus == cmmfGrantedWithMods)) {          /* The CA didn't give us the cert as we requested. */          goto loser;      }      currCert = CMMF_CertResponseGetCertificate(currResponse, 						 connection->m_certdb);      if (currCert == NULL) {          goto loser;      }      dbCert = CERT_FindCertByDERCert(connection->m_certdb,                                       &currCert->derCert);      if (dbCert != NULL) {        isPerm = dbCert->isperm;        CERT_DestroyCertificate(dbCert);        if (isPerm) {            /* This certificate already exists in the permanent             * database.  Let's not add it and continue on              * processing responses.             */            if (request.doBackup) {                certArr[i] = currCert;            } else {                CERT_DestroyCertificate(currCert);            }          CMMF_DestroyCertResponse(currResponse);          continue;        }      }            if (currCert->subjectList && currCert->subjectList->entry &&           currCert->subjectList->entry->nickname) {          nickname = currCert->subjectList->entry->nickname;      } else if (request.nickname == NULL || request.nickname[0] == '\0') {          nickname = default_nickname(currCert);          freeLocalNickname = PR_TRUE;       } else {          nickname = request.nickname;      }      slot = PK11_ImportCertForKey(currCert, nickname, connection);      if (freeLocalNickname) {          PR_Free(nickname);          freeLocalNickname = PR_FALSE;      }      if (slot == NULL) {          goto loser;      }      SSM_UseAsDefaultEmailIfNoneSet(connection, currCert, PR_TRUE);      if (request.doBackup) {          certArr[i] = currCert;      } else {          CERT_DestroyCertificate(currCert);      }      PK11_FreeSlot(slot);      CMMF_DestroyCertResponse(currResponse);  }  caPubs = CMMF_CertRepContentGetCAPubs(certRepContent);  if (caPubs != NULL) {      CERTCertListNode *node;      /* We got some CA certs to install in the database */      ourPool = PORT_NewArena(CRMF_DEFAULT_ARENA_SIZE);      if (ourPool == NULL) {          goto loser;      }      derCerts = PORT_ArenaNewArray(ourPool, SECItem,                                     SSM_CertListCount(caPubs));      if (derCerts == NULL) {          goto loser;      }      for (node = CERT_LIST_HEAD(caPubs), i=0;            !CERT_LIST_END(node, caPubs);           node = CERT_LIST_NEXT(node), i++) {          srv = SECITEM_CopyItem(ourPool, &derCerts[i], &node->cert->derCert);          if (srv != SECSuccess) {              goto loser;          }      }      srv = CERT_ImportCAChain(derCerts, SSM_CertListCount(caPubs),                               certUsageUserCertImport);      if (srv != SECSuccess) {          goto loser;      }      PORT_FreeArena(ourPool, PR_FALSE);  }  CMMF_DestroyCertRepContent(certRepContent);  if (request.doBackup) {      p12Create.isExportContext = PR_TRUE;      rv = SSM_CreateResource(SSM_RESTYPE_PKCS12_CONTEXT,                               (void*)&p12Create,                              connection, &p12RID,                              (SSMResource**)(&p12Cxt));      p12Cxt->arg = SSM_ZNEW(SSMPKCS12BackupThreadArg);      if (p12Cxt->arg == NULL) {          goto loser;      }      p12Cxt->arg->certs = certArr;      p12Cxt->arg->numCerts = numResponses;      p12Cxt->super.m_clientContext = request.clientContext;      p12Cxt->m_thread = SSM_CreateThread(&p12Cxt->super,                                  SSMPKCS12Context_BackupMultipleCertsThread);                                            }  PR_Free(request.base64Der);  PR_Free(request.nickname);  PR_FREEIF(msg->data);  msg->data = NULL;  msg->len = 0;  msg->type = (SECItemType)(SSM_REPLY_OK_MESSAGE | SSM_CRMF_ACTION |                             SSM_PROCESS_CMMF_RESP);  if (ssmcontrolconnection_send_message_to_client(connection, msg)       != SSM_SUCCESS){      goto loser;  }  SSM_FreeResource(&connection->super.super);  SECITEM_FreeItem(msg, PR_TRUE);  return; loser:  if (ourPool != NULL) {      PORT_FreeArena(ourPool, PR_FALSE);  }  if (certRepContent != NULL) {      CMMF_DestroyCertRepContent(certRepContent);  }  if (request.base64Der != NULL) {      PR_Free(request.base64Der);  }  if (request.nickname != NULL) {      PR_Free(request.nickname);  }  rv = ssmcontrolconnection_encode_err_reply(msg, SSM_FAILURE);  PR_ASSERT(rv == SSM_SUCCESS);  rv = ssmcontrolconnection_send_message_to_client(connection, msg);  PR_ASSERT(rv == SSM_SUCCESS);}SSMStatus SSM_ProcessCMMFCertResponse(SECItem *msg, SSMControlConnection *connection){    CMMFResponseArg *arg=NULL;    arg = SSM_NEW(CMMFResponseArg);    if (arg == NULL) {        goto loser;    }    arg->msg = SECITEM_DupItem(msg);    arg->connection = connection;    SSM_GetResourceReference(&connection->super.super);    if (SSM_CreateAndRegisterThread(PR_USER_THREAD,                                     ssm_processcmmfresponse_thread,                                    (void *)arg, PR_PRIORITY_NORMAL,                                     PR_LOCAL_THREAD,                                    PR_UNJOINABLE_THREAD, 0) == NULL) {        goto loser;    }    return SSM_ERR_DEFER_RESPONSE;     loser:    PR_FREEIF(arg);    return SSM_FAILURE;}SECKEYPrivateKey*SSM_FindPrivKeyFromKeyID(SECItem *keyID, SECMODModule *currMod,                         SSMControlConnection *ctrl){    PK11SlotInfo     *currSlot;    SECKEYPrivateKey *privKey = NULL;    int               i;    for (i=0; i<currMod->slotCount; i++) {        currSlot = currMod->slots[i];        privKey = PK11_FindKeyByKeyID(currSlot, keyID, (void*)ctrl);        if (privKey != NULL) {            break;        }    }    return privKey;}SECKEYPrivateKey*SSM_FindPrivKeyFromPubValue(SECItem *publicValue, SECMODModuleList *modList,                            SSMControlConnection *ctrl){    SECItem          *keyID = NULL;    SECMODModuleList *currMod;    SECKEYPrivateKey *privKey = NULL;    keyID = PK11_MakeIDFromPubKey(publicValue);    if (keyID == NULL) {        return NULL;    }    /* Iterate through the slots looking for the slot where the private      * key lives.     */    currMod = modList;    while (currMod != NULL && currMod->module != NULL) {        privKey = SSM_FindPrivKeyFromKeyID(keyID, currMod->module, ctrl);        if (privKey != NULL) {            break;        }        currMod = currMod->next;    }    SECITEM_FreeItem(keyID, PR_TRUE);    return privKey;}SSMStatusSSM_InitCRMFASN1Arg(CRMFASN1Arg *arg){    arg->buffer.data = SSM_NEW_ARRAY(unsigned char, DEFAULT_ASN1_CHUNK_SIZE);    if (arg->buffer.data == NULL) {        return PR_FAILURE;    }    arg->buffer.len   = 0;    arg->allocatedLen = DEFAULT_ASN1_CHUNK_SIZE;    return PR_FAILURE;}voidSSM_GenericASN1Callback(void *arg, const char *buf, unsigned long len){    CRMFASN1Arg   *encoderArg = (CRMFASN1Arg*)arg;    unsigned char *cursor;        if ((encoderArg->buffer.len + len) > encoderArg->allocatedLen) {        int newSize = encoderArg->buffer.len + DEFAULT_ASN1_CHUNK_SIZE;        void *dummy = PR_Realloc(encoderArg->buffer.data, newSize);        if (dummy == NULL) {            PR_ASSERT(0);            return;        }        encoderArg->buffer.data  = (unsigned char *) dummy;        encoderArg->allocatedLen = newSize;    }    cursor = &(encoderArg->buffer.data[encoderArg->buffer.len]);    memcpy(cursor, buf, len);    encoderArg->buffer.len += len;}SSMStatusSSM_RespondToPOPChallenge(SECItem                *msg,                           SSMControlConnection   *ctrl,                          char                  **challengeResponse,                           PRUint32               *responseLen){    SSMStatus   rv;    SECStatus  srv;    char      *challengeString = NULL;    SECItem    challengeDER = {siBuffer, NULL, 0}, *publicValue=NULL;    int        i, numChallenges;    long      *decryptedChallenges=NULL;    CMMFPOPODecKeyChallContent *challContent = NULL;    SECMODModuleList           *modList = NULL;    PK11SlotInfo               *slot = NULL;    SECKEYPrivateKey           *privKey = NULL;    CRMFASN1Arg                 asn1Arg = {(SECItemType) 0, NULL, 0};    SingleStringMessage request;    if (CMT_DecodeMessage(SingleStringMessageTemplate, &request, (CMTItem*)msg) != CMTSuccess) {        goto loser;    }    srv = ATOB_ConvertAsciiToItem(&challengeDER, request.string);    if (srv != SECSuccess) {        goto loser;    }    challContent = CMMF_CreatePOPODecKeyChallContentFromDER((char *) challengeDER.data,                                                            (unsigned int) challengeDER.len);    if (challContent == NULL) {        goto loser;    }    numChallenges = CMMF_POPODecKeyChallContentGetNumChallenges(challContent);    if (numChallenges <= 0) {        /* There weren't any challenges in the challenge string. */        goto loser;    }    modList = SECMOD_GetDefaultModuleList();    if (modList == NULL) {        goto loser;    }    decryptedChallenges = SSM_ZNEW_ARRAY(long, (numChallenges+1));    if (decryptedChallenges == NULL) {        goto loser;    }    for (i=0; i<numChallenges; i++) {        publicValue =             CMMF_POPODecKeyChallContentGetPublicValue(challContent, i);        if (publicValue == NULL) {            goto loser;        }        privKey = SSM_FindPrivKeyFromPubValue(publicValue, modList, ctrl);        if (privKey == NULL) {            goto loser;        }        SECITEM_FreeItem(publicValue, PR_TRUE);        publicValue = NULL;        srv = CMMF_POPODecKeyChallContDecryptChallenge(challContent, i,                                                       privKey);        if (srv != SECSuccess) {            goto loser;        }        srv = CMMF_POPODecKeyChallContentGetRandomNumber(challContent, i,                                                     &decryptedChallenges[i]);        if (srv != SECSuccess) {            goto loser;        }    }    modList = NULL;    CMMF_DestroyPOPODecKeyChallContent(challContent);    challContent = NULL;    rv = SSM_InitCRMFASN1Arg(&asn1Arg);    srv = CMMF_EncodePOPODecKeyRespContent(decryptedChallenges, numChallenges,                                           SSM_GenericASN1Callback, &asn1Arg);    if (srv != SECSuccess) {        goto loser;    }    *challengeResponse = BTOA_DataToAscii(asn1Arg.buffer.data,                                           asn1Arg.buffer.len);    PR_Free(asn1Arg.buffer.data);    *responseLen = (*challengeResponse == NULL) ? 0 :                                                   strlen(*challengeResponse)+1;    PR_Free(decryptedChallenges);    PR_Free(request.string);    return PR_SUCCESS; loser:    if (asn1Arg.buffer.data != NULL) {        PR_Free(asn1Arg.buffer.data);    }    if (decryptedChallenges != NULL) {        PR_Free(decryptedChallenges);    }    if (request.string != NULL) {        PR_Free(request.string);    }    if (challContent != NULL) {        CMMF_DestroyPOPODecKeyChallContent(challContent);    }    if (publicValue != NULL) {        SECITEM_FreeItem(publicValue, PR_TRUE);    }    if (modList != NULL) {        SECMOD_DestroyModuleList(modList);    }    return PR_FAILURE;}void SSM_CRMFEncodeThread(void *arg){   SSMCRMFThreadArg     *encArg = (SSMCRMFThreadArg*)arg;    SSMControlConnection *ctrl   = encArg->ctrl;   SECItem              *msg    = encArg->msg;   char                 *encodedReq = NULL;   PRUint32              derLen;   SingleItemMessage reply;   SSMStatus rv;   SSM_RegisterThread("CRMF Encode", NULL);   SSM_DEBUG("Encoding CRMF request(s)\n");   rv = SSM_EncodeCRMFRequests(ctrl, msg, &encodedReq, &derLen);   if (rv != PR_SUCCESS) {       goto loser;   }   msg->data = NULL;   msg->len  = 0;   msg->type = (SECItemType) (SSM_REPLY_OK_MESSAGE |                               SSM_CRMF_ACTION      |                              SSM_DER_ENCODE_REQ);   reply.item.len = derLen;   reply.item.data = (unsigned char *) encodedReq;   if (CMT_EncodeMessage(SingleItemMessageTemplate,                          (CMTItem*)msg, &reply) != CMTSuccess) {       goto loser;   }   SSM_DEBUG("Created the following request: \n");   SSM_DEBUG("\n%s\n",encodedReq);   PR_Free(encodedReq);   SSM_DEBUG("queueing reply: type %lx, len %ld.\n", msg->type, msg->len);   SSM_SendQMessage(ctrl->m_controlOutQ,                    SSM_PRIORITY_NORMAL,                    msg->type, msg->len,                    (char *)msg->data, PR_TRUE);   goto done; loser:  {    SingleNumMessage reply;    msg->type = (SECItemType) SSM_REPLY_ERR_MESSAGE;    reply.value = rv;    CMT_EncodeMessage(SingleNumMessageTemplate, (CMTItem*)msg, &reply);  }  SSM_DEBUG("queueing reply: type %lx, len %ld.\n", msg->type, msg->len);  SSM_SendQMessage(ctrl->m_controlOutQ,                   SSM_PRIORITY_NORMAL,                   msg->type, msg->len,                   (char *)msg->data, PR_TRUE); done:  SSM_FreeResource(&ctrl->super.super);  SECITEM_FreeItem(msg, PR_TRUE);  PR_Free(arg);}

⌨️ 快捷键说明

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