oldfunc.c

来自「支持SSL v2/v3, TLS, PKCS #5, PKCS #7, PKCS」· C语言 代码 · 共 1,322 行 · 第 1/3 页

C
1,322
字号
    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);    if (!certificate_conflict(ctrl, &cert->derCert, 			      ctrl->m_certdb, PR_TRUE)) {      /*       * This cert is already in the database, no need to re-import.       */      goto loser;    }    /* 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, ctrl);    /*    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;}PRBoolcertificate_conflict(SSMControlConnection * cx, SECItem * derCert,                      CERTCertDBHandle * handle, PRBool sendUIEvent){   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 (sendUIEvent && (SSMControlConnection_SendUIEvent(cx,                                                 "get", "cert_already_exists",						NULL, NULL, NULL, PR_TRUE)) == 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, PR_TRUE);  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, SSMControlConnection *conn){     char *username = NULL;  char *caname = NULL;  char *nickname = NULL;  char *tmp = NULL;  int count;  CERTCertificate *dummycert;  SSMTextGenContext *cx = NULL;  PK11SlotInfo *slot=NULL;  CK_OBJECT_HANDLE keyHandle;  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) {      goto loser;    }    if (SSM_FindUTF8StringInBundles(cx, "nick_template_with_num", 				    &nickFmtWithNum) != SSM_SUCCESS) {      goto loser;    }  }  nickname = PR_smprintf(nickFmt, username, caname);  /*   * We need to see if the private key exists on a token, if it does   * then we need to check for nicknames that already exist on the smart   * card.   */  slot = PK11_KeyForCertExists(cert, &keyHandle, conn);  if (slot == NULL) {    goto loser;  }  if (!PK11_IsInternal(slot)) {    tmp = PR_smprintf("%s:%s", PK11_GetTokenName(slot), nickname);    PR_Free(nickname);    nickname = tmp;    tmp = NULL;  }  tmp = nickname;  while ( 1 ) {	    if ( count > 1 ) {      nickname = PR_smprintf("%s #%d", tmp, count);    }        if ( nickname == NULL )       goto loser;     _ssm_compress_spaces(nickname);    if (PK11_IsInternal(slot)) {      /* look up the nickname to make sure it isn't in use already */      dummycert = CERT_FindCertByNickname(conn->m_certdb, nickname);          } else {      /*       * Check the cert against others that already live on the smart        * card.       */      dummycert = PK11_FindCertFromNickname(nickname, conn);      if (dummycert != NULL) {	/*	 * Make sure the subject names are different.	 */ 	if (CERT_CompareName(&cert->subject, &dummycert->subject) == SECEqual)	{	  /*

⌨️ 快捷键说明

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