Exemplo n.º 1
0
void
OCSPCache::LogWithCerts(const char* aMessage, const CERTCertificate* aCert,
                        const CERTCertificate* aIssuerCert)
{
#ifdef PR_LOGGING
  if (PR_LOG_TEST(gCertVerifierLog, PR_LOG_DEBUG)) {
    mozilla::pkix::ScopedPtr<char, mozilla::psm::PORT_Free_string>
      cn(CERT_GetCommonName(&aCert->subject));
    mozilla::pkix::ScopedPtr<char, mozilla::psm::PORT_Free_string>
      cnIssuer(CERT_GetCommonName(&aIssuerCert->subject));
    PR_LOG(gCertVerifierLog, PR_LOG_DEBUG, (aMessage, cn.get(), cnIssuer.get()));
  }
#endif
}
Exemplo n.º 2
0
/*
 * Host name checking according to RFC 2595.
 */
static enum okay
nss_check_host(const char *server, struct sock *sp)
{
	CERTCertificate	*cert;
	char	*cn = NULL;
	enum okay	ok = STOP;
	PRArenaPool	*arena;
	CERTGeneralName	*gn;
	SECItem	altname;
	CERTAltNameEncodedContext	ec;
	int	i;
	const SEC_ASN1Template	gntempl[] = {
		{ SEC_ASN1_SEQUENCE_OF, 0, SEC_AnyTemplate }
	};

	if ((cert = SSL_PeerCertificate(sp->s_prfd)) == NULL) {
		fprintf(stderr, "no certificate from \"%s\"\n", server);
		return STOP;
	}
	arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
	if (CERT_FindCertExtension(cert, SEC_OID_X509_SUBJECT_ALT_NAME,
				&altname) == SECSuccess &&
			SEC_ASN1DecodeItem(arena, &ec, gntempl,
				&altname) == SECSuccess &&
			ec.encodedGenName != NULL) {
		for (i = 0; ec.encodedGenName[i] != NULL; i++) {
			gn = CERT_DecodeGeneralName(arena, ec.encodedGenName[i],
					NULL);
			if (gn->type == certDNSName) {
				char	*dn = ac_alloc(gn->name.other.len + 1);
				memcpy(dn, gn->name.other.data,
						gn->name.other.len);
				dn[gn->name.other.len] = '\0';
				if (verbose)
					fprintf(stderr,
						"Comparing DNS name: \"%s\"\n",
						dn);
				if (rfc2595_hostname_match(server, dn)
						== OKAY) {
					ac_free(dn);
					goto out;
				}
				ac_free(dn);
			}
		}
	}
	if ((cn = CERT_GetCommonName(&cert->subject)) != NULL) {
		if (verbose)
			fprintf(stderr, "Comparing common name: \"%s\"\n", cn);
		ok = rfc2595_hostname_match(server, cn);
	}
	if (ok == STOP)
		fprintf(stderr, "host certificate does not match \"%s\"\n",
				server);
out:	if (cn)
		PORT_Free(cn);
	PORT_FreeArena(arena, PR_FALSE);
	CERT_DestroyCertificate(cert);
	return ok;
}
Exemplo n.º 3
0
static void display_cert_info(struct SessionHandle *data,
                              CERTCertificate *cert)
{
  char *subject, *issuer, *common_name;
  PRExplodedTime printableTime;
  char timeString[256];
  PRTime notBefore, notAfter;

  subject = CERT_NameToAscii(&cert->subject);
  issuer = CERT_NameToAscii(&cert->issuer);
  common_name = CERT_GetCommonName(&cert->subject);
  infof(data, "\tsubject: %s\n", subject);

  CERT_GetCertTimes(cert, &notBefore, &notAfter);
  PR_ExplodeTime(notBefore, PR_GMTParameters, &printableTime);
  PR_FormatTime(timeString, 256, "%b %d %H:%M:%S %Y GMT", &printableTime);
  infof(data, "\tstart date: %s\n", timeString);
  PR_ExplodeTime(notAfter, PR_GMTParameters, &printableTime);
  PR_FormatTime(timeString, 256, "%b %d %H:%M:%S %Y GMT", &printableTime);
  infof(data, "\texpire date: %s\n", timeString);
  infof(data, "\tcommon name: %s\n", common_name);
  infof(data, "\tissuer: %s\n", issuer);

  PR_Free(subject);
  PR_Free(issuer);
  PR_Free(common_name);
}
Exemplo n.º 4
0
Arquivo: nss.c Projeto: flashfoxter/sx
int sxi_vcrypt_print_cert_info(sxc_client_t *sx, const char *file, int batch_mode)
{
    struct PK11_ctx ctx;
    CERTCertificate *cert = load_cert_file(sx, file, &ctx);

    if(!cert) {
        free_PK11_ctx(&ctx);
        return -1;
    }

    if (cert && !batch_mode) {
        char *subject = CERT_NameToAscii(&cert->subject);
        char *issuer = CERT_NameToAscii(&cert->issuer);
        char *common_name = CERT_GetCommonName(&cert->subject);
        struct sxi_fmt fmt;
        char hash[SXI_SHA1_TEXT_LEN+1];

        sxi_fmt_start(&fmt);
        sxi_fmt_msg(&fmt, "\tSubject: %s\n", subject);
        sxi_fmt_msg(&fmt, "\tIssuer: %s\n", issuer);
        if (!sxi_conns_hashcalc_core(sx, NULL, 0,
                                     cert->derCert.data,
                                     cert->derCert.len, hash)) {
            sxi_fmt_msg(&fmt, "\tSHA1 Fingerprint: %s\n", hash);
        }
        sxi_info(sx, "%s", fmt.buf);
        PR_Free(subject);
        PR_Free(issuer);
        PR_Free(common_name);
    }

    CERT_DestroyCertificate(cert);
    free_PK11_ctx(&ctx);
    return 0;
}
Exemplo n.º 5
0
/* readonly attribute string windowTitle; */
NS_IMETHODIMP 
nsNSSCertificate::GetWindowTitle(char * *aWindowTitle)
{
  nsNSSShutDownPreventionLock locker;
  if (isAlreadyShutDown())
    return NS_ERROR_NOT_AVAILABLE;

  NS_ENSURE_ARG(aWindowTitle);
  if (mCert) {
    if (mCert->nickname) {
      *aWindowTitle = PL_strdup(mCert->nickname);
    } else {
      *aWindowTitle = CERT_GetCommonName(&mCert->subject);
      if (!*aWindowTitle) {
        if (mCert->subjectName) {
          *aWindowTitle = PL_strdup(mCert->subjectName);
        } else if (mCert->emailAddr) {
          *aWindowTitle = PL_strdup(mCert->emailAddr);
        } else {
          *aWindowTitle = PL_strdup("");
        }
      }
    }
  } else {
    NS_ERROR("Somehow got nullptr for mCertificate in nsNSSCertificate.");
    *aWindowTitle = nullptr;
  }
  return NS_OK;
}
Exemplo n.º 6
0
char*
DefaultServerNicknameForCert(CERTCertificate* cert)
{
  char* nickname = nullptr;
  int count;
  bool conflict;
  char* servername = nullptr;

  servername = CERT_GetCommonName(&cert->subject);
  if (!servername) {
    // Certs without common names are strange, but they do exist...
    // Let's try to use another string for the nickname
    servername = CERT_GetOrgUnitName(&cert->subject);
    if (!servername) {
      servername = CERT_GetOrgName(&cert->subject);
      if (!servername) {
        servername = CERT_GetLocalityName(&cert->subject);
        if (!servername) {
          servername = CERT_GetStateName(&cert->subject);
          if (!servername) {
            servername = CERT_GetCountryName(&cert->subject);
            if (!servername) {
              // We tried hard, there is nothing more we can do.
              // A cert without any names doesn't really make sense.
              return nullptr;
            }
          }
        }
      }
    }
  }

  count = 1;
  while (1) {
    if (count == 1) {
      nickname = PR_smprintf("%s", servername);
    }
    else {
      nickname = PR_smprintf("%s #%d", servername, count);
    }
    if (!nickname) {
      break;
    }

    conflict = SEC_CertNicknameConflict(nickname, &cert->derSubject,
                                        cert->dbhandle);
    if (!conflict) {
      break;
    }
    PR_Free(nickname);
    count++;
  }
  PR_FREEIF(servername);
  return nickname;
}
Exemplo n.º 7
0
/*
 * NSS_CMSSignerInfo_GetSignerCommonName - return the common name of the signer
 *
 * sinfo - signerInfo data for this signer
 *
 * Returns a pointer to allocated memory, which must be freed with PORT_Free.
 * A return value of NULL is an error.
 */
char *
NSS_CMSSignerInfo_GetSignerCommonName(NSSCMSSignerInfo *sinfo)
{
    CERTCertificate *signercert;

    /* will fail if cert is not verified */
    if ((signercert = NSS_CMSSignerInfo_GetSigningCertificate(sinfo, NULL)) == NULL)
	return NULL;

    return (CERT_GetCommonName(&signercert->subject));
}
Exemplo n.º 8
0
static SECStatus BadCertHandler(void *arg, PRFileDesc *sock)
{
  SECStatus result = SECFailure;
  struct connectdata *conn = (struct connectdata *)arg;
  PRErrorCode err = PR_GetError();
  CERTCertificate *cert = NULL;
  char *subject, *subject_cn, *issuer;

  conn->data->set.ssl.certverifyresult=err;
  cert = SSL_PeerCertificate(sock);
  subject = CERT_NameToAscii(&cert->subject);
  subject_cn = CERT_GetCommonName(&cert->subject);
  issuer = CERT_NameToAscii(&cert->issuer);
  CERT_DestroyCertificate(cert);

  switch(err) {
  case SEC_ERROR_CA_CERT_INVALID:
    infof(conn->data, "Issuer certificate is invalid: '%s'\n", issuer);
    break;
  case SEC_ERROR_UNTRUSTED_ISSUER:
    infof(conn->data, "Certificate is signed by an untrusted issuer: '%s'\n",
          issuer);
    break;
  case SSL_ERROR_BAD_CERT_DOMAIN:
    if(conn->data->set.ssl.verifyhost) {
      failf(conn->data, "SSL: certificate subject name '%s' does not match "
            "target host name '%s'", subject_cn, conn->host.dispname);
    }
    else {
      result = SECSuccess;
      infof(conn->data, "warning: SSL: certificate subject name '%s' does not "
            "match target host name '%s'\n", subject_cn, conn->host.dispname);
    }
    break;
  case SEC_ERROR_EXPIRED_CERTIFICATE:
    infof(conn->data, "Remote Certificate has expired.\n");
    break;
  case SEC_ERROR_UNKNOWN_ISSUER:
    infof(conn->data, "Peer's certificate issuer is not recognized: '%s'\n",
          issuer);
    break;
  default:
    infof(conn->data, "Bad certificate received. Subject = '%s', "
          "Issuer = '%s'\n", subject, issuer);
    break;
  }
  if(result == SECSuccess)
    infof(conn->data, "SSL certificate verify ok.\n");
  PR_Free(subject);
  PR_Free(subject_cn);
  PR_Free(issuer);

  return result;
}
Exemplo n.º 9
0
NS_IMETHODIMP
nsNSSCertificate::GetIssuerCommonName(nsAString &aCommonName)
{
  nsNSSShutDownPreventionLock locker;
  if (isAlreadyShutDown())
    return NS_ERROR_NOT_AVAILABLE;

  aCommonName.Truncate();
  if (mCert) {
    char *commonName = CERT_GetCommonName(&mCert->issuer);
    if (commonName) {
      aCommonName = NS_ConvertUTF8toUTF16(commonName);
      PORT_Free(commonName);
    }
  }
  return NS_OK;
}
Exemplo n.º 10
0
static void display_conn_info(struct connectdata *conn, PRFileDesc *sock)
{
  SSLChannelInfo channel;
  SSLCipherSuiteInfo suite;
  CERTCertificate *cert;
  char *subject, *issuer, *common_name;
  PRExplodedTime printableTime;
  char timeString[256];
  PRTime notBefore, notAfter;

  if(SSL_GetChannelInfo(sock, &channel, sizeof channel) ==
     SECSuccess && channel.length == sizeof channel &&
     channel.cipherSuite) {
    if(SSL_GetCipherSuiteInfo(channel.cipherSuite,
                              &suite, sizeof suite) == SECSuccess) {
      infof(conn->data, "SSL connection using %s\n", suite.cipherSuiteName);
    }
  }

  infof(conn->data, "Server certificate:\n");

  cert = SSL_PeerCertificate(sock);
  subject = CERT_NameToAscii(&cert->subject);
  issuer = CERT_NameToAscii(&cert->issuer);
  common_name = CERT_GetCommonName(&cert->subject);
  infof(conn->data, "\tsubject: %s\n", subject);

  CERT_GetCertTimes(cert, &notBefore, &notAfter);
  PR_ExplodeTime(notBefore, PR_GMTParameters, &printableTime);
  PR_FormatTime(timeString, 256, "%b %d %H:%M:%S %Y GMT", &printableTime);
  infof(conn->data, "\tstart date: %s\n", timeString);
  PR_ExplodeTime(notAfter, PR_GMTParameters, &printableTime);
  PR_FormatTime(timeString, 256, "%b %d %H:%M:%S %Y GMT", &printableTime);
  infof(conn->data, "\texpire date: %s\n", timeString);
  infof(conn->data, "\tcommon name: %s\n", common_name);
  infof(conn->data, "\tissuer: %s\n", issuer);

  PR_Free(subject);
  PR_Free(issuer);
  PR_Free(common_name);

  CERT_DestroyCertificate(cert);

  return;
}
Exemplo n.º 11
0
NS_IMETHODIMP
nsNSSCertificate::GetCommonName(nsAString &aCommonName)
{
  nsNSSShutDownPreventionLock locker;
  if (isAlreadyShutDown())
    return NS_ERROR_NOT_AVAILABLE;

  aCommonName.Truncate();
  if (mCert) {
    char *commonName = CERT_GetCommonName(&mCert->subject);
    if (commonName) {
      aCommonName = NS_ConvertUTF8toUTF16(commonName);
      PORT_Free(commonName);
    } /*else {
      *aCommonName = ToNewUnicode(NS_LITERAL_STRING("<not set>")), 
    }*/
  }
  return NS_OK;
}
Exemplo n.º 12
0
std::string SslSocket::getClientAuthId() const
{
    std::string authId;
    CERTCertificate* cert = SSL_PeerCertificate(nssSocket);
    if (cert) {
        char *cn = CERT_GetCommonName(&(cert->subject));
        if (cn) {
            authId = std::string(cn);
            /*
             * The NSS function CERT_GetDomainComponentName only returns
             * the last component of the domain name, so we have to parse
             * the subject manually to extract the full domain.
             */
            std::string domain = getDomainFromSubject(cert->subjectName);
            if (!domain.empty()) {
                authId += DOMAIN_SEPARATOR;
                authId += domain;
            }
        }
        CERT_DestroyCertificate(cert);
    }
    return authId;
}
Exemplo n.º 13
0
static
void checkName(CERTName *n, char *fieldName, int verbose)
{
    char *v=0;
    if (verbose) {
	printf("Checking %s\n", fieldName);
    }

    v = CERT_GetCountryName(n);
    if (!v) {
	printf("PROBLEM: %s lacks Country Name (C)\n",
	       fieldName);
    }
    PORT_Free(v);

    v = CERT_GetOrgName(n);
    if (!v) {
	printf("PROBLEM: %s lacks Organization Name (O)\n",
	       fieldName);
    }
    PORT_Free(v);

    v = CERT_GetOrgUnitName(n);
    if (!v) {
	printf("WARNING: %s lacks Organization Unit Name (OU)\n",
	       fieldName);
    }
    PORT_Free(v);	

    v = CERT_GetCommonName(n);
    if (!v) {
	printf("PROBLEM: %s lacks Common Name (CN)\n",
	       fieldName);
    }
    PORT_Free(v);
}
Exemplo n.º 14
0
static void
AppendErrorTextMismatch(const nsString &host,
                        nsIX509Cert* ix509,
                        nsINSSComponent *component,
                        bool wantsHtml,
                        nsString &returnedMessage)
{
    const char16_t *params[1];
    nsresult rv;

    ScopedCERTCertificate nssCert(ix509->GetCert());

    if (!nssCert) {
        // We are unable to extract the valid names, say "not valid for name".
        params[0] = host.get();
        nsString formattedString;
        rv = component->PIPBundleFormatStringFromName("certErrorMismatch",
                params, 1,
                formattedString);
        if (NS_SUCCEEDED(rv)) {
            returnedMessage.Append(formattedString);
            returnedMessage.Append('\n');
        }
        return;
    }

    nsString allNames;
    uint32_t nameCount = 0;
    bool useSAN = false;

    if (nssCert)
        useSAN = GetSubjectAltNames(nssCert.get(), component, allNames, nameCount);

    if (!useSAN) {
        char *certName = CERT_GetCommonName(&nssCert->subject);
        if (certName) {
            nsDependentCSubstring commonName(certName, strlen(certName));
            if (IsUTF8(commonName)) {
                // Bug 1024781
                // We should actually check that the common name is a valid dns name or
                // ip address and not any string value before adding it to the display
                // list.
                ++nameCount;
                allNames.Assign(NS_ConvertUTF8toUTF16(commonName));
            }
            PORT_Free(certName);
        }
    }

    if (nameCount > 1) {
        nsString message;
        rv = component->GetPIPNSSBundleString("certErrorMismatchMultiple",
                                              message);
        if (NS_SUCCEEDED(rv)) {
            returnedMessage.Append(message);
            returnedMessage.AppendLiteral("\n  ");
            returnedMessage.Append(allNames);
            returnedMessage.AppendLiteral("  \n");
        }
    }
    else if (nameCount == 1) {
        const char16_t *params[1];
        params[0] = allNames.get();

        const char *stringID;
        if (wantsHtml)
            stringID = "certErrorMismatchSingle2";
        else
            stringID = "certErrorMismatchSinglePlain";

        nsString formattedString;
        rv = component->PIPBundleFormatStringFromName(stringID,
                params, 1,
                formattedString);
        if (NS_SUCCEEDED(rv)) {
            returnedMessage.Append(formattedString);
            returnedMessage.Append('\n');
        }
    }
    else { // nameCount == 0
        nsString message;
        nsresult rv = component->GetPIPNSSBundleString("certErrorMismatchNoNames",
                      message);
        if (NS_SUCCEEDED(rv)) {
            returnedMessage.Append(message);
            returnedMessage.Append('\n');
        }
    }
}
Exemplo n.º 15
0
static void
AppendErrorTextMismatch(const nsString &host,
                        nsIX509Cert* ix509,
                        nsINSSComponent *component,
                        bool wantsHtml,
                        nsString &returnedMessage)
{
  const char16_t *params[1];
  nsresult rv;

  mozilla::pkix::ScopedCERTCertificate nssCert;

  nsCOMPtr<nsIX509Cert2> cert2 = do_QueryInterface(ix509, &rv);
  if (cert2)
    nssCert = cert2->GetCert();

  if (!nssCert) {
    // We are unable to extract the valid names, say "not valid for name".
    params[0] = host.get();
    nsString formattedString;
    rv = component->PIPBundleFormatStringFromName("certErrorMismatch", 
                                                  params, 1, 
                                                  formattedString);
    if (NS_SUCCEEDED(rv)) {
      returnedMessage.Append(formattedString);
      returnedMessage.Append(NS_LITERAL_STRING("\n"));
    }
    return;
  }

  nsString allNames;
  uint32_t nameCount = 0;
  bool useSAN = false;

  if (nssCert)
    useSAN = GetSubjectAltNames(nssCert.get(), component, allNames, nameCount);

  if (!useSAN) {
    char *certName = nullptr;
    // currently CERT_FindNSStringExtension is not being exported by NSS.
    // If it gets exported, enable the following line.
    //   certName = CERT_FindNSStringExtension(nssCert, SEC_OID_NS_CERT_EXT_SSL_SERVER_NAME);
    // However, it has been discussed to treat the extension as obsolete and ignore it.
    if (!certName)
      certName = CERT_GetCommonName(&nssCert->subject);
    if (certName) {
      nsDependentCSubstring commonName(certName, strlen(certName));
      if (IsUTF8(commonName)) {
        // Bug 1024781
        // We should actually check that the common name is a valid dns name or
        // ip address and not any string value before adding it to the display
        // list.
        ++nameCount;
        allNames.Assign(NS_ConvertUTF8toUTF16(commonName));
      }
      PORT_Free(certName);
    }
  }

  if (nameCount > 1) {
    nsString message;
    rv = component->GetPIPNSSBundleString("certErrorMismatchMultiple", 
                                          message);
    if (NS_SUCCEEDED(rv)) {
      returnedMessage.Append(message);
      returnedMessage.Append(NS_LITERAL_STRING("\n  "));
      returnedMessage.Append(allNames);
      returnedMessage.Append(NS_LITERAL_STRING("  \n"));
    }
  }
  else if (nameCount == 1) {
    const char16_t *params[1];
    params[0] = allNames.get();
    
    const char *stringID;
    if (wantsHtml)
      stringID = "certErrorMismatchSingle2";
    else
      stringID = "certErrorMismatchSinglePlain";

    nsString formattedString;
    rv = component->PIPBundleFormatStringFromName(stringID, 
                                                  params, 1, 
                                                  formattedString);
    if (NS_SUCCEEDED(rv)) {
      returnedMessage.Append(formattedString);
      returnedMessage.Append(NS_LITERAL_STRING("\n"));
    }
  }
  else { // nameCount == 0
    nsString message;
    nsresult rv = component->GetPIPNSSBundleString("certErrorMismatchNoNames",
                                                   message);
    if (NS_SUCCEEDED(rv)) {
      returnedMessage.Append(message);
      returnedMessage.Append(NS_LITERAL_STRING("\n"));
    }
  }
}
Exemplo n.º 16
0
void
nsNSSCertificateDB::get_default_nickname(CERTCertificate *cert, 
                                         nsIInterfaceRequestor* ctx,
                                         nsCString &nickname)
{
  nickname.Truncate();

  nsNSSShutDownPreventionLock locker;
  nsresult rv;
  CK_OBJECT_HANDLE keyHandle;

  CERTCertDBHandle *defaultcertdb = CERT_GetDefaultCertDB();
  nsCOMPtr<nsINSSComponent> nssComponent(do_GetService(kNSSComponentCID, &rv));
  if (NS_FAILED(rv))
    return;

  nsCAutoString username;
  char *temp_un = CERT_GetCommonName(&cert->subject);
  if (temp_un) {
    username = temp_un;
    PORT_Free(temp_un);
    temp_un = nsnull;
  }

  nsCAutoString caname;
  char *temp_ca = CERT_GetOrgName(&cert->issuer);
  if (temp_ca) {
    caname = temp_ca;
    PORT_Free(temp_ca);
    temp_ca = nsnull;
  }

  nsAutoString tmpNickFmt;
  nssComponent->GetPIPNSSBundleString("nick_template", tmpNickFmt);
  NS_ConvertUTF16toUTF8 nickFmt(tmpNickFmt);

  nsCAutoString baseName;
  char *temp_nn = PR_smprintf(nickFmt.get(), username.get(), caname.get());
  if (!temp_nn) {
    return;
  } else {
    baseName = temp_nn;
    PR_smprintf_free(temp_nn);
    temp_nn = nsnull;
  }

  nickname = baseName;

  /*
   * 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.
   */
  PK11SlotInfo *slot = PK11_KeyForCertExists(cert, &keyHandle, ctx);
  PK11SlotInfoCleaner slotCleaner(slot);
  if (!slot)
    return;

  if (!PK11_IsInternal(slot)) {
    char *tmp = PR_smprintf("%s:%s", PK11_GetTokenName(slot), baseName.get());
    if (!tmp) {
      nickname.Truncate();
      return;
    }
    baseName = tmp;
    PR_smprintf_free(tmp);

    nickname = baseName;
  }

  int count = 1;
  while (true) {
    if ( count > 1 ) {
      char *tmp = PR_smprintf("%s #%d", baseName.get(), count);
      if (!tmp) {
        nickname.Truncate();
        return;
      }
      nickname = tmp;
      PR_smprintf_free(tmp);
    }

    CERTCertificate *dummycert = nsnull;
    CERTCertificateCleaner dummycertCleaner(dummycert);

    if (PK11_IsInternal(slot)) {
      /* look up the nickname to make sure it isn't in use already */
      dummycert = CERT_FindCertByNickname(defaultcertdb, nickname.get());

    } else {
      /*
       * Check the cert against others that already live on the smart 
       * card.
       */
      dummycert = PK11_FindCertFromNickname(nickname.get(), ctx);
      if (dummycert != NULL) {
	/*
	 * Make sure the subject names are different.
	 */ 
	if (CERT_CompareName(&cert->subject, &dummycert->subject) == SECEqual)
	{
	  /*
	   * There is another certificate with the same nickname and
	   * the same subject name on the smart card, so let's use this
	   * nickname.
	   */
	  CERT_DestroyCertificate(dummycert);
	  dummycert = NULL;
	}
      }
    }
    if (!dummycert) 
      break;
    
    count++;
  }
}