📄 kgenctxt.c
字号:
/* If the context is already exiting due to an error, abort the key generation. */ rv = SSMRESOURCE(ct)->m_status; if (rv != PR_SUCCESS) goto loser; /* Restore parameters from the message. */ keyGenMechanism = kg->keyGenMechanism; kp = kg->kp; actualParams = kg->actualParams; /* Finish key generation. */ if (ct->mech != kg->keyGenMechanism) { goto loser; } slot = ct->slot; if (!slot) goto loser; SSM_DEBUG("Creating key pair.\n"); privKey = PK11_GenerateKeyPair(slot, keyGenMechanism, actualParams, &pubKey, PR_TRUE, PR_TRUE, NULL); if ((!privKey) || (!pubKey)) { rv = PR_FAILURE; goto loser; } /* Put the newly generated keys into the key pair object. */ kp->m_PubKey = pubKey; kp->m_PrivKey = privKey; /* Set the wincx of the private key so that crypto operations * that use the signing key as the source for the wincx pass * a non NULL value to the authentication functions. */ kp->m_PrivKey->wincx = kp->super.m_connection; goto done; loser: if (rv == PR_SUCCESS) rv = PR_FAILURE; /* Destroy keys if we've generated them. */ if (pubKey) SECKEY_DestroyPublicKey(pubKey); if (privKey) SECKEY_DestroyPrivateKey(privKey);#if 0 /* Remove and destroy key pair object. */ if (ct->m_keys && kp) SSM_Remove(ct->m_keys, kp); if (kp) /* should only be one ref outstanding */ SSM_FreeResource(&kp->super);#endif done: /* Free the PKCS11 key gen params. */ if (actualParams != NULL) ssm_FreeKeyGenParams(keyGenMechanism, actualParams); /* Free the queued key gen message. */ PR_FREEIF(kg); SSM_DEBUG("FinishGeneratingKeyPair returned rv = %d.\n", rv); return rv;}voidSSMKeyGenContext_SendCompleteEvent(SSMKeyGenContext *ct){ SSMStatus rv = PR_SUCCESS; PR_ASSERT(ct->m_parent); if (ct->m_parent) { SECItem msg; TaskCompletedEvent event; /* Assemble the event. */ SSM_DEBUG("Task completed event: id %ld, count %ld, status %d\n", SSMRESOURCE(ct)->m_id, ct->m_count, SSMRESOURCE(ct)->m_status); event.resourceID = SSMRESOURCE(ct)->m_id; event.numTasks = ct->m_count; event.result = SSMRESOURCE(ct)->m_status; if (CMT_EncodeMessage(TaskCompletedEventTemplate, (CMTItem*)&msg, (CMTItem*)&event) != CMTSuccess) { return; } if (msg.data) { /* Send the event to the control queue. */ rv = SSM_SendQMessage(ct->m_parent->m_controlOutQ, SSM_PRIORITY_NORMAL, SSM_EVENT_MESSAGE | SSM_TASK_COMPLETED_EVENT, (int) msg.len, (char *) msg.data, PR_FALSE); SSM_DEBUG("Sent message, rv = %d.\n", rv); } }}SSMStatusSSMKeyGenContext_SendEscrowWarning(SSMKeyGenContext *ct, SSMEscrowWarnParam *escrowParam){ SSMStatus rv; rv = SSMControlConnection_SendUIEvent(SSMRESOURCE(ct)->m_connection, "get", "escrow_warning", SSMRESOURCE(ct), NULL, &SSMRESOURCE(ct)->m_clientContext); if (rv != SSM_SUCCESS) { goto loser; } PR_ASSERT(SSMRESOURCE(ct)->m_buttonType == SSM_BUTTON_NONE); while (SSMRESOURCE(ct)->m_buttonType == SSM_BUTTON_NONE) { SSM_WaitForOKCancelEvent(SSMRESOURCE(ct), PR_INTERVAL_NO_TIMEOUT); } /* ### sjlee: this unfortunate fix is due to the fact that bad things * happen if we do not finish closing the window before * another window pops up: this will be supplanted by a * more complete fix later */ PR_Sleep(PR_TicksPerSecond()*2); return (SSMRESOURCE(ct)->m_buttonType == SSM_BUTTON_OK) ? PR_SUCCESS : PR_FAILURE; loser: return PR_FAILURE;}static SSMStatusssmkg_DoKeyEscrowWarning(SSMKeyGenContext *ct){ int i; SSMStatus rv = PR_SUCCESS; if (ct->m_eaCert == NULL) { /* No Escrow Authority Certificate, return Success so that * key generation continues. */ return PR_SUCCESS; } for (i=0; i < ct->m_numKeyGens; i++) { if (ct->m_keyGens[i]->kp->m_KeyGenType == rsaEnc) { rv = SSMKeyGenContext_SendEscrowWarning(ct, NULL); break; } } return rv;}SSMStatusSSMKeyGenContext_GenerateAllKeys(SSMKeyGenContext *ct){ SSMStatus rv = PR_FAILURE; int i; /* Make sure the UI is up before we start. */ PR_Sleep(PR_TicksPerSecond()*2); /* First figure out if we are going to try and escrow, * pop up UI if we are */ rv = ssmkg_DoKeyEscrowWarning(ct); if (rv != PR_SUCCESS) { /* Tell the service thread to shut itself down. */ SSM_SendQMessage(ct->m_incomingQ, SSM_PRIORITY_SHUTDOWN, SSM_DATA_PROVIDER_SHUTDOWN, 0, NULL, PR_TRUE); goto loser; } /* * We'll force all key gens to use the same mechanism so that when * we create dual keys, we won't prompt the user multiple times for * a slot to create the keys on. */ PR_ASSERT(ct->m_numKeyGens > 0); ct->mech = ct->m_keyGens[0]->keyGenMechanism; rv = SSMKeyGenContext_GetSlot(ct, ct->mech); if (rv != SSM_SUCCESS) goto loser; for (i=0; i<ct->m_numKeyGens; i++) { /* Lock so that we can finish a keygen without the state changing underneath us. */ SSM_DEBUG("Waiting for lock in order to start new keygen.\n", rv); SSM_LockResource(SSMRESOURCE(ct)); /* Do key generation. */ rv = SSMKeyGenContext_FinishGeneratingKeyPair(ct, ct->m_keyGens[i]); /* No matter what, update the completed count. */ ct->m_count++; /* Having finished the request, send back a Context Completed event describing our results. */ SSM_DEBUG("Sending Task Completed event to client.\n", rv); SSMKeyGenContext_SendCompleteEvent(ct); /* Unlock the object so that the canceller can work. */ SSM_UnlockResource(SSMRESOURCE(ct)); } loser: if (SSMRESOURCE(ct)->m_status != PR_SUCCESS) { rv = SSMRESOURCE(ct)->m_status; } return rv;}voidSSMKeyGenContext_ServiceThread(void *arg){ SSMKeyGenContext *ct = (SSMKeyGenContext *) arg; SSMResource *res = SSMRESOURCE(ct); PRInt32 type, len; char *url = NULL; char *data = NULL; char *tmp = NULL; SSMStatus rv = PR_SUCCESS; PRBool processingKeys = PR_FALSE; SECItem msg;#if 0 SSMEscrowWarnParam *escrowParam = NULL;#endif CreateResourceReply reply; PR_ASSERT(ct); PR_ASSERT(SSM_IsAKindOf(SSMRESOURCE(ct), SSM_RESTYPE_KEYGEN_CONTEXT)); SSM_RegisterNewThread("keygen", (SSMResource*)arg); SSM_DEBUG("Sending Create Resource response to client.\n"); reply.result = PR_SUCCESS; reply.resID = SSMRESOURCE(ct)->m_id; if (CMT_EncodeMessage(CreateResourceReplyTemplate, (CMTItem*)&msg, &reply) != CMTSuccess) { goto loser; } if (!msg.data || !msg.len) { rv = PR_OUT_OF_MEMORY_ERROR; goto loser; } /* Post the message on the outgoing control channel. */ PR_ASSERT(SSM_IsAKindOf(&(ct->m_parent->super.super), SSM_RESTYPE_CONTROL_CONNECTION)); rv = SSM_SendQMessage(ct->m_parent->m_controlOutQ, SSM_PRIORITY_NORMAL, SSM_REPLY_OK_MESSAGE | SSM_RESOURCE_ACTION | SSM_CREATE_RESOURCE, (int) msg.len, (char *) msg.data, PR_FALSE); if (rv != PR_SUCCESS) goto loser; /* Start serving key gen requests. */ while(1) { /* Get the next request from the queue. If we've been cancelled or if there's an error, drain what we have but don't wait around. */ SSM_DEBUG("Reading message from queue.\n");#if 1 if (processingKeys) {#endif SSM_DEBUG("Looking for keygen requests (and anything else).\n"); rv = SSM_RecvQMessage(ct->m_incomingQ, SSM_PRIORITY_ANY, &type, &len, &data, (SSMRESOURCE(ct)->m_status == PR_SUCCESS));#if 1 } else { SSM_DEBUG("Looking only for open/shutdown messages.\n"); rv = SSM_RecvQMessage(ct->m_incomingQ, SSM_PRIORITY_SHUTDOWN, &type, &len, &data, PR_TRUE); }#endif SSM_DEBUG("rv = %d reading from queue.\n", rv); if (rv != SSM_SUCCESS) goto loser; /* If it's a keygen request, then attend to it. */ switch (type) { case SSM_KEYGEN_CXT_MESSAGE_DATA_PROVIDER_OPEN: processingKeys = PR_TRUE; break; case SSM_KEYGEN_CXT_MESSAGE_DATA_PROVIDER_SHUTDOWN: goto loser; /*destroy object */ case SSM_KEYGEN_CXT_MESSAGE_GEN_KEY: if (!processingKeys) { SSM_DEBUG("**** Dropping keygen request on the floor ****\n"); break; } rv = SSMKeyGenContext_GenerateAllKeys(ct); break; default: SSM_DEBUG("Don't understand this request.\n"); /* ### mwelch Don't know what to do with this request */ rv = (SSMStatus) SSM_ERR_BAD_REQUEST; break; } } loser: SSM_LockResource(res); /* De-register ourselves from the resource thread count. */ if (PR_GetCurrentThread() == ct->m_serviceThread) { ct->m_serviceThread = NULL; } res->m_threadCount--; SSM_UnlockResource(res); PR_FREEIF(tmp); PR_FREEIF(url); SSM_DEBUG("Shutting down keygen context.\n"); SSM_ShutdownResource(SSMRESOURCE(ct), rv); SSM_FreeResource(SSMRESOURCE(ct)); SSM_DEBUG("Exiting, status %d.\n", rv);}voidSSMKeyGenContext_CancelKeyGen(SSMKeyGenContext *ct){ /* set the status so that subsequent keygen attempts will drop out */ SSM_ShutdownResource(SSMRESOURCE(ct), SSM_ERR_USER_CANCEL); ct->m_userCancel = PR_TRUE; SSMRESOURCE(ct)->m_status = SSM_ERR_USER_CANCEL;}SSMStatusSSMKeyGenContext_FinishGeneratingAllKeyPairs(SSMControlConnection *ctrl, SECItem *msg){ SSMStatus rv; SSMKeyGenContext *ct; SingleNumMessage request; SSM_DEBUG("SSMKeyGenContext_FinishGeneratingAllKeyPairs...\n"); if (CMT_DecodeMessage(SingleNumMessageTemplate, &request, (CMTItem*)msg) != CMTSuccess) { goto loser; } rv = SSMControlConnection_GetResource(ctrl, request.value, (SSMResource **) &ct); if (rv != PR_SUCCESS) { goto loser; } if (!ct || !SSM_IsAKindOf(SSMRESOURCE(ct), SSM_RESTYPE_KEYGEN_CONTEXT)) { rv = PR_INVALID_ARGUMENT_ERROR; goto loser; } if (ct->m_userCancel) return (SSMStatus)SSM_ERR_USER_CANCEL; rv = SSM_SendQMessage(ct->m_incomingQ, SSM_PRIORITY_NORMAL, SSM_KEYGEN_CXT_MESSAGE_GEN_KEY, 0, NULL, PR_FALSE); loser: return rv;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -