📄 crmfres.c
字号:
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 + -