📄 oldfunc.c
字号:
if ( challenge ) { pkac.challenge.len = PORT_Strlen(challenge); } else { pkac.challenge.len = 0; } pkac.challenge.data = (unsigned char *)challenge; rv = DER_Encode(arena, &pkacItem, CERTPublicKeyAndChallengeTemplate, &pkac); if ( rv != SECSuccess ) { goto done; } /* * now sign the DER encoded PublicKeyAndChallenge */ rv = SEC_DerSignData(arena, &signedItem, pkacItem.data, pkacItem.len, privateKey, algTag); if ( rv != SECSuccess ) { goto done; } /* * Convert the signed public key and challenge into base64/ascii. */ keystring = BTOA_DataToAscii(signedItem.data, signedItem.len); done: /* * Destroy the private key ASAP, so that we don't leave a copy in * memory that some evil hacker can get at. */ if ( rv != SECSuccess ) { if ( privateKey ) { PK11_DestroyTokenObject(privateKey->pkcs11Slot,privateKey->pkcs11ID); SECKEY_DestroyPrivateKey(privateKey); } if ( publicKey ) PK11_DestroyTokenObject(publicKey->pkcs11Slot,publicKey->pkcs11ID); } if ( spkInfo ) SECKEY_DestroySubjectPublicKeyInfo(spkInfo); if ( publicKey ) SECKEY_DestroyPublicKey(publicKey); if ( arena ) PORT_FreeArena(arena, PR_TRUE); return keystring;}static SECStatuscollect_certs(void *arg, SECItem **certs, int numcerts){ CERTDERCerts *collectArgs; SECItem *cert; SECStatus rv; collectArgs = (CERTDERCerts *)arg; collectArgs->numcerts = numcerts; collectArgs->rawCerts = (SECItem *) PORT_ArenaZAlloc(collectArgs->arena, sizeof(SECItem) * numcerts); if ( collectArgs->rawCerts == NULL ) return(SECFailure); cert = collectArgs->rawCerts; while ( numcerts-- ) { rv = SECITEM_CopyItem(collectArgs->arena, cert, *certs); if ( rv == SECFailure ) return(SECFailure); cert++; certs++; } return (SECSuccess);}static SSMStatus handle_user_cert(SSMControlConnection * ctrl, CERTCertificate *cert, CERTDERCerts *derCerts){ PK11SlotInfo *slot; char * nickname = NULL; SECStatus rv; int numCACerts; SECItem *CACerts; slot = PK11_KeyForCertExists(cert, NULL, ctrl); if ( slot == NULL ) { SSM_DEBUG("Can't find keydb with the key for the new cert!\n"); goto loser; } PK11_FreeSlot(slot); /* pick a nickname for the cert */ if (cert->subjectList && cert->subjectList->entry && cert->subjectList->entry->nickname) nickname = cert->subjectList->entry->nickname; else nickname = default_nickname(cert); /* UI for cert installation goes here - no UI here? */ /* user wants to import the cert */ slot = PK11_ImportCertForKey(cert, nickname, ctrl); if (!slot) goto loser; PK11_FreeSlot(slot); SSM_UseAsDefaultEmailIfNoneSet(ctrl, cert, PR_FALSE); numCACerts = derCerts->numcerts - 1; if (numCACerts) { CACerts = derCerts->rawCerts+1; rv = CERT_ImportCAChain(CACerts, numCACerts, certUsageUserCertImport); /* We really should send some notice to the user that importing the * CA certs failed if rv is SECSuccess. */ } return PR_SUCCESS; loser: CERT_DestroyCertificate(cert); return PR_FAILURE;}static SSMStatus handle_ca_cert(SSMControlConnection * ctrl, CERTCertificate *cert, CERTDERCerts *derCerts){ caImportCertArg * arg = NULL; arg = (caImportCertArg *) PORT_ZAlloc(sizeof(caImportCertArg)); arg->ctrl = ctrl; arg->cert = CERT_DupCertificate(cert); arg->derCerts = derCerts; SSM_CreateAndRegisterThread(PR_USER_THREAD, SSM_ImportCACert, (void *)arg, PR_PRIORITY_NORMAL, PR_LOCAL_THREAD, PR_UNJOINABLE_THREAD, 0); return PR_SUCCESS;}static PRBoolcertificate_conflict(void * cx, SECItem * derCert, CERTCertDBHandle * handle){ SECStatus rv; SECItem key; PRArenaPool *arena = NULL; PRBool ret; CERTCertificate *cert; arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE); if (!arena) goto loser; /* get the key (issuer+cn) from the cert */ rv = CERT_KeyFromDERCert(arena, derCert, &key); if ( rv != SECSuccess ) goto loser; /* check if the same cert already exists */ cert = CERT_FindCertByKey(handle, &key); if ( cert ) { if ( cert->isperm && ( cert->nickname == NULL ) && ( cert->emailAddr == NULL ) ) { /* if the cert doesn't have a nickname or email addr, it is * bogus cruft, so delete it */ SEC_DeletePermCertificate(cert); } else if ( cert->isperm ) { SSM_DEBUG("Found existing cert with the same key!\n"); rv = SECFailure; if ((SSMControlConnection_SendUIEvent((SSMControlConnection *)cx, "get", "cert_already_exists", NULL, NULL, NULL)) == SSM_SUCCESS) rv = SECSuccess; ret = PR_FALSE; goto done; } else CERT_DestroyCertificate(cert); } /* end of same-cert-exists */ ret = PR_TRUE; goto done; loser: ret = PR_FALSE;done: if ( arena ) PORT_FreeArena(arena, PR_FALSE); return ret;}typedef struct UserCertImprtArgStr { SSMControlConnection *ctrl; SECItem *msg;} UserCertImportArg;void ssm_import_user_cert_thread(void *arg) { UserCertImportArg *impArg = (UserCertImportArg*)arg; SSMControlConnection *ctrl = impArg->ctrl; SECItem *msg = impArg->msg; SSMStatus rv = PR_FAILURE; CERTDERCerts * collectArgs; PRArenaPool *arena; CERTCertificate * cert=NULL; SSMResourceID certID; SSMResource * certResource; PRBool noconflict; DecodeAndCreateTempCertRequest request; SingleNumMessage reply; if (!msg || !msg->data) goto loser; SSM_RegisterThread("cert import", NULL); if (CMT_DecodeMessage(DecodeAndCreateTempCertRequestTemplate, &request, (CMTItem*)msg) != CMTSuccess) { goto loser; } arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE); if ( arena == NULL ) goto loser; collectArgs = (CERTDERCerts *)PORT_ArenaZAlloc(arena, sizeof(CERTDERCerts)); if ( collectArgs == NULL ) goto loser; collectArgs->arena = arena; rv = CERT_DecodeCertPackage((char *) request.cert.data, (int) request.cert.len, collect_certs, (void *)collectArgs); if (rv != PR_SUCCESS) goto loser; /* check for conflicts */ noconflict = certificate_conflict(ctrl,collectArgs->rawCerts,ctrl->m_certdb); if (!noconflict) goto loser; /* certificate with this key already exists in the db */ cert = CERT_NewTempCertificate(ctrl->m_certdb, collectArgs->rawCerts, (char *)NULL, PR_FALSE, PR_TRUE); if (!cert) goto loser; /* create certificate resource so we can return it to client */ rv = SSM_CreateResource(SSM_RESTYPE_CERTIFICATE, cert, ctrl, &certID, &certResource); if (rv != PR_SUCCESS) { SSM_DEBUG("In decode&create tmp cert: can't create certificate resource.\n"); goto loser; } /* Get a client reference to it */ SSM_ClientGetResourceReference(certResource, &certID); switch (request.type) { case SEC_CERT_CLASS_USER: rv = handle_user_cert(ctrl, cert, collectArgs); break; case SEC_CERT_CLASS_CA: rv = handle_ca_cert(ctrl, cert, collectArgs); break; case SEC_CERT_CLASS_SERVER: /* why destroy class server certs? */ CERT_DestroyCertificate(cert); break; case SEC_CERT_CLASS_EMAIL: rv = handle_email_cert(ctrl, cert, collectArgs); break; default: rv = PR_FAILURE; SSM_DEBUG("ProcessDecodeAndCreateCertRequest: unknown cert class\n"); } if (rv != PR_SUCCESS) goto loser; /* create reply */ msg->type = (SECItemType) (SSM_REPLY_OK_MESSAGE | SSM_CERT_ACTION | SSM_DECODE_TEMP_CERT); msg->len = 0; reply.value = certID; if (CMT_EncodeMessage(SingleNumMessageTemplate, (CMTItem*)msg, &reply) != CMTSuccess) { goto loser; } 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); if (rv == PR_SUCCESS) goto done; loser: { SingleNumMessage reply; msg->type = (SECItemType) SSM_REPLY_ERR_MESSAGE; reply.value = rv; CMT_EncodeMessage(SingleNumMessageTemplate, (CMTItem*)msg, &reply); if (!msg->data || msg->len == 0) goto loser; else rv = PR_SUCCESS; } 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); if (rv == PR_SUCCESS) rv = PR_FAILURE; if (arena) PORT_FreeArena(arena, PR_TRUE); done: SECITEM_FreeItem(msg, PR_TRUE); SSM_FreeResource(&ctrl->super.super); if (cert != NULL) CERT_DestroyCertificate(cert); return;}SSMStatusSSMControlConnection_ProcessDecodeAndCreateTempCert(SSMControlConnection * ctrl, SECItem * msg){ UserCertImportArg *impArg; impArg = SSM_ZNEW(UserCertImportArg); if (impArg == NULL) { return SSM_FAILURE; } impArg->ctrl = ctrl; impArg->msg = SECITEM_DupItem(msg); SSMControlConnection_RecycleItem(msg); SSM_GetResourceReference(&ctrl->super.super); if (SSM_CreateAndRegisterThread(PR_USER_THREAD, ssm_import_user_cert_thread, (void*)impArg, PR_PRIORITY_NORMAL, PR_LOCAL_THREAD, PR_UNJOINABLE_THREAD, 0) == NULL) { SSM_DEBUG("Couldn't create thread for importing cert."); return SSM_FAILURE; } return SSM_ERR_DEFER_RESPONSE;}static SSMStatus handle_email_cert(SSMControlConnection * ctrl, CERTCertificate * cert, CERTDERCerts * derCerts){ SSMStatus rv = PR_FAILURE; SECItem **rawCerts; int numcerts; int i; numcerts = derCerts->numcerts; rawCerts = (SECItem **) PORT_Alloc(sizeof(SECItem *) * numcerts); if ( !rawCerts ) goto loser; for ( i = 0; i < numcerts; i++ ) { rawCerts[i] = &derCerts->rawCerts[i]; } rv = CERT_ImportCerts(cert->dbhandle, certUsageEmailSigner, numcerts, rawCerts, NULL, PR_TRUE, PR_FALSE, NULL); if ( rv == SECSuccess ) { rv = CERT_SaveSMimeProfile(cert, NULL, NULL); } PORT_Free(rawCerts); loser: return rv;}char *default_nickname(CERTCertificate *cert){ char *username = NULL; char *caname = NULL; char *nickname = NULL; int count; CERTCertificate *dummycert; SSMTextGenContext *cx = NULL; username = CERT_GetCommonName(&cert->subject); if ( username == NULL ) username = strdup(""); if ( username == NULL ) goto loser; caname = CERT_GetOrgName(&cert->issuer); if ( caname == NULL ) caname = strdup(""); if ( caname == NULL ) goto loser; count = 1; if (nickFmt == NULL) { if (SSMTextGen_NewTopLevelContext(NULL, &cx) != SSM_SUCCESS) { goto loser; } if (SSM_FindUTF8StringInBundles(cx, "nick_template", &nickFmt) != SSM_SUCCESS) {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -