📄 p12res.c
字号:
} fprintf(stderr,"\n"); for(i=0; i< *outBufLen; i++) { fprintf(stderr,"%2x ", (char) outBuf[i]); } fprintf(stderr,"\n\n");#endif return retval;}static SECStatusssmpkcs12context_digestopen(void *arg, PRBool readData){ char *tmpFileName=NULL; char filePathSep; SSMPKCS12Context *cxt = (SSMPKCS12Context *)arg;#if defined(XP_UNIX) filePathSep = '/';#elif defined(WIN32) filePathSep = '\\';#elif defined(XP_MAC) filePathSep = ':';#else#error Tell me what the file path separator is of this platform.#endif tmpFileName = PR_smprintf("%s%c%s", SSMRESOURCE(cxt)->m_connection->m_dirRoot, filePathSep, ".nsm_p12_tmp"); if (tmpFileName == NULL) { return SECFailure; } if (readData) { cxt->m_digestFile = PR_Open(tmpFileName, PR_RDONLY, 0400); } else { cxt->m_digestFile = PR_Open(tmpFileName, PR_CREATE_FILE | PR_RDWR | PR_TRUNCATE, 0600); } cxt->m_tempFilePath = tmpFileName; if (cxt->m_digestFile == NULL) { cxt->m_error = PR_TRUE; return SECFailure; } return SECSuccess;}static SECStatusssmpkcs12context_digestclose(void *arg, PRBool removeFile){ SSMPKCS12Context *cxt = (SSMPKCS12Context*)arg; if (cxt == NULL || cxt->m_digestFile == NULL) { return SECFailure; } PR_Close(cxt->m_digestFile); cxt->m_digestFile = NULL; if (removeFile) { PR_Delete(cxt->m_tempFilePath); PR_Free(cxt->m_tempFilePath); cxt->m_tempFilePath = NULL; } return SECSuccess;}static intssmpkcs12context_digestread(void *arg, unsigned char *buf, unsigned long len){ SSMPKCS12Context *cxt = (SSMPKCS12Context*)arg; if (cxt == NULL || cxt->m_digestFile == NULL) { return -1; } if (buf == NULL || len == 0) { return -1; } return PR_Read(cxt->m_digestFile, buf, len);}static intssmpkcs12context_digestwrite(void *arg, unsigned char *buf, unsigned long len){ SSMPKCS12Context *cxt = (SSMPKCS12Context *)arg; if (cxt == NULL || cxt->m_digestFile == NULL) { return -1; } if (buf == NULL || len == 0) { return -1; } return PR_Write(cxt->m_digestFile, buf, len);}SECItem*SSM_NicknameCollisionCallback(SECItem *old_nick, PRBool *cancel, void *wincx){ /* We don't handle this yet */ *cancel = PR_TRUE; return NULL;}static PK11SlotInfo*SSMPKCS12Context_ChooseSlotForImport(SSMPKCS12Context *cxt, PK11SlotList *slotList){ char mech[20]; SSMStatus rv; PR_snprintf(mech, 20, "mech=%d", CKM_RSA_PKCS); SSM_LockUIEvent(&cxt->super); rv = SSMControlConnection_SendUIEvent(cxt->super.m_connection, "get", "select_token", &cxt->super, mech, &SSMRESOURCE(cxt)->m_clientContext); if (rv != SSM_SUCCESS) { SSM_UnlockResource(&cxt->super); return NULL; } SSM_WaitUIEvent(&cxt->super, PR_INTERVAL_NO_TIMEOUT); /* Wait so damn window goes away without swallowing up * the password prompt that will come up next. */ PR_Sleep(PR_TicksPerSecond()); return (PK11SlotInfo*)cxt->super.m_uiData;}static PK11SlotInfo*SSMPKCS12Context_GetSlotForImport(SSMPKCS12Context *cxt){ PK11SlotList *slotList; PK11SlotInfo *slot = NULL; slotList = PK11_GetAllTokens(CKM_RSA_PKCS, PR_TRUE, PR_TRUE, cxt->super.m_connection); if (slotList == NULL || slotList->head == NULL) { /* Couldn't find a slot, let's try the internal slot * and see what happens */ slot = PK11_GetInternalKeySlot(); } else if (slotList->head->next == NULL) { /* * Only one slot, return it. */ slot = PK11_ReferenceSlot(slotList->head->slot); } else { slot = SSMPKCS12Context_ChooseSlotForImport(cxt, slotList); } if (slotList) PK11_FreeSlotList(slotList); return slot;}SSMStatusSSMPKCS12Context_RestoreCertFromPKCS12File(SSMPKCS12Context *cxt){ SSMStatus rv; SECItem passwdReq; char *prompt=NULL; PK11SlotInfo *slot=NULL; SEC_PKCS12DecoderContext *p12dcx=NULL; PRBool swapUnicode = PR_FALSE; unsigned char *buf=NULL; SECItem pwItem = { siBuffer, NULL, 0 }, uniPwItem = { siBuffer, NULL, 0 }; SECStatus srv; CERTCertList *certList=NULL; CERTCertListNode *node=NULL; PromptRequest request; if (cxt == NULL || cxt->m_isExportContext) { return SSM_FAILURE; }#ifdef IS_LITTLE_ENDIAN swapUnicode = PR_TRUE;#endif rv = SSM_RequestFilePathFromUser(SSMRESOURCE(cxt), "pkcs12_import_file_prompt", "*.p12", PR_TRUE); if (rv != SSM_SUCCESS || cxt->super.m_fileName == NULL) { rv = SSM_ERR_BAD_FILENAME; goto loser; } prompt = SSM_GetCharFromKey("pkcs12_request_password_prompt", "ISO-8859-1"); if (prompt == NULL) { rv = SSM_FAILURE; goto loser; } request.resID = SSMRESOURCE(cxt)->m_id; request.prompt = prompt; request.clientContext = SSMRESOURCE(cxt)->m_clientContext; if (CMT_EncodeMessage(PromptRequestTemplate, (CMTItem*)&passwdReq, &request) != CMTSuccess) { rv = SSM_FAILURE; goto loser; } passwdReq.type = (SECItemType) (SSM_EVENT_MESSAGE | SSM_PROMPT_EVENT); SSM_LockResource(SSMRESOURCE(cxt)); cxt->m_password = NULL; rv = SSM_SendQMessage(SSMRESOURCE(cxt)->m_connection->m_controlOutQ, 20, passwdReq.type, passwdReq.len, (char*)passwdReq.data, PR_TRUE); SSM_WaitResource(SSMRESOURCE(cxt), SSM_PASSWORD_WAIT_TIME); SSM_UnlockResource(SSMRESOURCE(cxt)); if (cxt->m_password == NULL) { rv = SSM_ERR_NO_PASSWORD; goto loser; } cxt->m_file = PR_Open(SSMRESOURCE(cxt)->m_fileName, PR_RDONLY, 0400); if (cxt->m_file == NULL) { rv = SSM_ERR_BAD_FILENAME; goto loser; } slot = SSMPKCS12Context_GetSlotForImport(cxt); if (slot == NULL) { goto loser; } if (PK11_NeedLogin(slot)) { /* we should log out only if the slot needs login */ PK11_Logout(slot); } /* User has not initialize DB, ask for a password. */ if (PK11_NeedUserInit(slot)) { rv = SSM_SetUserPassword(slot, SSMRESOURCE(cxt)); if (rv != SSM_SUCCESS) { rv = SSM_ERR_NEED_USER_INIT_DB; goto loser; } } if (PK11_Authenticate(slot, PR_FALSE, SSMRESOURCE(cxt)->m_connection) != SECSuccess) { rv = SSM_ERR_BAD_DB_PASSWORD; goto loser; } pwItem.data = (unsigned char *) cxt->m_password; pwItem.len = strlen(cxt->m_password); if (SSM_UnicodeConversion(&uniPwItem, &pwItem, PR_TRUE, swapUnicode) != SECSuccess) { rv = SSM_ERR_BAD_PASSWORD; goto loser; } p12dcx = SEC_PKCS12DecoderStart(&uniPwItem, slot, SSMRESOURCE(cxt)->m_connection, ssmpkcs12context_digestopen, ssmpkcs12context_digestclose, ssmpkcs12context_digestread, ssmpkcs12context_digestwrite, cxt); if (p12dcx == NULL) { rv = SSM_FAILURE; goto loser; } buf = SSM_NEW_ARRAY(unsigned char, PKCS12_IN_BUFFER_SIZE); if (buf == NULL) { rv = SSM_ERR_OUT_OF_MEMORY; goto loser; } cxt->m_file = PR_Open(SSMRESOURCE(cxt)->m_fileName, PR_RDONLY, 0400); if (cxt->m_file == NULL) { rv = SSM_ERR_BAD_FILENAME; goto loser; } while (PR_TRUE) { int readLen = PR_Read(cxt->m_file, buf, PKCS12_IN_BUFFER_SIZE); if (readLen < 0) { rv = SSM_FAILURE; goto loser; } srv = SEC_PKCS12DecoderUpdate(p12dcx, buf, readLen); if (srv != SECSuccess || readLen != PKCS12_IN_BUFFER_SIZE) { break; } } if (srv != SECSuccess) { rv = SSM_ERR_CANNOT_DECODE; goto loser; } if (SEC_PKCS12DecoderVerify(p12dcx) != SECSuccess) { rv = SSM_FAILURE; goto loser; } if (SEC_PKCS12DecoderValidateBags(p12dcx, SSM_NicknameCollisionCallback) != SECSuccess) { if (PORT_GetError() == SEC_ERROR_PKCS12_DUPLICATE_DATA) { rv = SSM_PKCS12_CERT_ALREADY_EXISTS; } else { rv = SSM_FAILURE; } goto loser; } if (SEC_PKCS12DecoderImportBags(p12dcx) != SECSuccess) { rv = SSM_FAILURE; goto loser; } PR_Close(cxt->m_file); cxt->m_file = NULL; PR_Free(prompt); PK11_FreeSlot(slot); certList = SEC_PKCS12DecoderGetCerts(p12dcx); if (certList != NULL) { for (node = CERT_LIST_HEAD(certList); !CERT_LIST_END(node, certList); node = CERT_LIST_NEXT(node)) { if ((node->cert->trust) && (node->cert->trust->emailFlags & CERTDB_USER) && CERT_VerifyCertNow(cxt->super.m_connection->m_certdb, node->cert, PR_TRUE, certUsageEmailSigner, cxt) == SSM_SUCCESS) { rv = SSM_UseAsDefaultEmailIfNoneSet(cxt->super.m_connection, node->cert, PR_FALSE); if (rv == SSM_SUCCESS) { /* We just made this cert the default new cert */ rv = SSM_ERR_NEW_DEF_MAIL_CERT; break; } } } CERT_DestroyCertList(certList); certList = NULL; } SEC_PKCS12DecoderFinish(p12dcx); return (rv == SSM_ERR_NEW_DEF_MAIL_CERT) ? rv : SSM_SUCCESS;loser: if (cxt->m_file != NULL) { PR_Close(cxt->m_file); cxt->m_file = NULL; } if (prompt != NULL) { PR_Free(prompt); } if (slot != NULL) { PK11_FreeSlot(slot); } if (p12dcx != NULL) { SEC_PKCS12DecoderFinish(p12dcx); } if (buf != NULL) { PR_Free(buf); } cxt->m_error = PR_TRUE; return rv;}SSMStatusSSMPKCS12Context_ProcessPromptReply(SSMResource *res, char *reply){ SSMPKCS12Context *cxt = (SSMPKCS12Context*)res; if (!SSM_IsAKindOf(res, SSM_RESTYPE_PKCS12_CONTEXT)) { return PR_FAILURE; } cxt->m_password = reply?PL_strdup(reply):NULL; SSM_LockResource(res); SSM_NotifyResource(res); SSM_UnlockResource(res); return PR_SUCCESS;}SSMStatusSSMPKCS12Context_Print(SSMResource *res, char *fmt, PRIntn numParams, char **value, char **resultStr){ char mechStr[48]; SSMStatus rv = SSM_FAILURE; PR_ASSERT(resultStr != NULL); if (resultStr == NULL) { rv = SSM_FAILURE; goto done; } if (numParams) { rv = SSMResource_Print(res, fmt, numParams, value, resultStr); goto done; } PR_snprintf(mechStr, 48, "%d", CKM_RSA_PKCS); *resultStr = PR_smprintf(fmt, res->m_id, mechStr, ""); rv = (*resultStr == NULL) ? SSM_FAILURE : SSM_SUCCESS; done: return rv;}void SSMPKCS12Context_BackupMultipleCertsThread(void *arg){ SSMPKCS12Context *p12Cxt = (SSMPKCS12Context*)arg; SSMStatus rv; SSMControlConnection *connection = p12Cxt->super.m_connection; PRIntn i; SSM_RegisterThread("PKCS12", NULL); SSM_DEBUG("About to backup some certs.\n"); rv = SSMControlConnection_SendUIEvent(connection, "get", "backup_new_cert", &p12Cxt->super, NULL, &p12Cxt->super.m_clientContext); PR_ASSERT(SSMRESOURCE(p12Cxt)->m_buttonType == SSM_BUTTON_NONE); if (rv == SSM_SUCCESS) { while (SSMRESOURCE(p12Cxt)->m_buttonType == SSM_BUTTON_NONE) { SSM_WaitForOKCancelEvent(SSMRESOURCE(p12Cxt), PR_INTERVAL_NO_TIMEOUT); } } /* * Even though we tell the old client to use a context it provided to us, * it still tries to use the top-most window to bring up the * next dialog. Meaning I still have to insert this sleep. * * XXX -javi */ PR_Sleep(PR_TicksPerSecond());#if 0 /* * Disable this for now, until we figure out how we're really going to * support putting multiple cert/key pairs in one P12 file. */ SSMPKCS12Context_CreatePKCS12FileForMultipleCerts(p12Cxt, PR_FALSE, p12Cxt->arg->certs, p12Cxt->arg->numCerts);#endif for (i=0; i<p12Cxt->arg->numCerts;i++) { p12Cxt->m_cert = p12Cxt->arg->certs[i]; SSMPKCS12Context_CreatePKCS12File(p12Cxt, PR_FALSE); /* * If we do more than one, then the old client crashes * because it tries to use a window that no longer exists as * the base for the next window. */ PR_Sleep(PR_TicksPerSecond()); } PR_Free(p12Cxt->arg->certs); PR_Free(p12Cxt->arg); p12Cxt->arg = NULL; p12Cxt->m_thread = NULL; SSM_FreeResource(&p12Cxt->super); SSM_DEBUG("Done backing up certs.\n");}SSMStatus SSM_WarnPKCS12Incompatibility(SSMTextGenContext *cx){ SSMStatus rv; char *value; rv = SSM_HTTPParamValue(cx->m_request, "multipleCerts", &value); PR_FREEIF(cx->m_result); cx->m_result = NULL; if (rv == SSM_SUCCESS) { rv = SSM_FindUTF8StringInBundles(cx, "pkcs12_incompatible_warn", &cx->m_result); if (rv != SSM_SUCCESS) { cx->m_result = PL_strdup(""); } } else { cx->m_result = PL_strdup(""); } return SSM_SUCCESS;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -