コード例 #1
0
NS_IMETHODIMP
nsNSSCertificateDB::FindCertByNickname(nsISupports *aToken,
                                      const nsAString &nickname,
                                      nsIX509Cert **_rvCert)
{
  nsNSSShutDownPreventionLock locker;
  CERTCertificate *cert = NULL;
  char *asciiname = NULL;
  NS_ConvertUTF16toUTF8 aUtf8Nickname(nickname);
  asciiname = const_cast<char*>(aUtf8Nickname.get());
  PR_LOG(gPIPNSSLog, PR_LOG_DEBUG, ("Getting \"%s\"\n", asciiname));
#if 0
  // what it should be, but for now...
  if (aToken) {
    cert = PK11_FindCertFromNickname(asciiname, NULL);
  } else {
    cert = CERT_FindCertByNickname(CERT_GetDefaultCertDB(), asciiname);
  }
#endif
  cert = PK11_FindCertFromNickname(asciiname, NULL);
  if (!cert) {
    cert = CERT_FindCertByNickname(CERT_GetDefaultCertDB(), asciiname);
  }
  if (cert) {
    PR_LOG(gPIPNSSLog, PR_LOG_DEBUG, ("got it\n"));
    nsCOMPtr<nsIX509Cert> pCert = new nsNSSCertificate(cert);
    CERT_DestroyCertificate(cert);
    *_rvCert = pCert;
    NS_ADDREF(*_rvCert);
    return NS_OK;
  }
  *_rvCert = nsnull;
  return NS_ERROR_FAILURE;
}
コード例 #2
0
ファイル: e_nss_cmd.c プロジェクト: BackupTheBerlios/enss-svn
static X509*
nss_get_cert(NSS_CTX *ctx, const char *s) {
    X509 *x509 = NULL;
    CERTCertificate *cert = NULL;

    CALL_TRACE("nss_get_cert...\n");

    if (ctx == NULL) {
        NSSerr(NSS_F_GET_CERT, NSS_R_INVALID_ARGUMENT);
        goto done;
    }
    if (!NSS_IsInitialized()) {
        NSSerr(NSS_F_GET_CERT, NSS_R_DB_IS_NOT_INITIALIZED);
        goto done;
    }

    nss_debug(ctx, "search certificate '%s'", s);
    cert = PK11_FindCertFromNickname(s, NULL);
    nss_trace(ctx, "found certificate mem='%p'", cert);

    if (cert == NULL) goto done;

    x509 = X509_from_CERTCertificate(cert);

done:
    if (cert) CERT_DestroyCertificate(cert);

    nss_debug(ctx, "certificate %s", (x509 ? "found": "not found"));
    return(x509);
}
コード例 #3
0
// nsPKCS12Blob::LoadCerts
//
// Given an array of certificate nicknames, load the corresponding
// certificates into a local array.
nsresult
nsPKCS12Blob::LoadCerts(const PRUnichar **certNames, int numCerts)
{
  nsresult rv;
  char namecpy[256];
  /* Create the local array if needed */
  if (!mCertArray) {
    rv = NS_NewISupportsArray(getter_AddRefs(mCertArray));
    if (NS_FAILED(rv)) {
      if (!handleError())
        return NS_ERROR_OUT_OF_MEMORY;
    }
  }
  /* Add the certs */
  for (int i=0; i<numCerts; i++) {
    strcpy(namecpy, NS_ConvertUTF16toUTF8(certNames[i]));
    CERTCertificate *nssCert = PK11_FindCertFromNickname(namecpy, NULL);
    if (!nssCert) {
      if (!handleError())
        return NS_ERROR_FAILURE;
      else continue; /* user may request to keep going */
    }
    nsCOMPtr<nsIX509Cert> cert = nsNSSCertificate::Create(nssCert);
    CERT_DestroyCertificate(nssCert);
    if (!cert) {
      if (!handleError())
        return NS_ERROR_OUT_OF_MEMORY;
    } else {
      mCertArray->AppendElement(cert);
    }
  }
  return NS_OK;
}
コード例 #4
0
ファイル: nss.c プロジェクト: 3s3s/simple_server
/**
 *
 * Check that the Peer certificate's issuer certificate matches the one found
 * by issuer_nickname.  This is not exactly the way OpenSSL and GNU TLS do the
 * issuer check, so we provide comments that mimic the OpenSSL
 * X509_check_issued function (in x509v3/v3_purp.c)
 */
static SECStatus check_issuer_cert(PRFileDesc *sock,
                                   char *issuer_nickname)
{
  CERTCertificate *cert,*cert_issuer,*issuer;
  SECStatus res=SECSuccess;
  void *proto_win = NULL;

  /*
    PRArenaPool   *tmpArena = NULL;
    CERTAuthKeyID *authorityKeyID = NULL;
    SECITEM       *caname = NULL;
  */

  cert = SSL_PeerCertificate(sock);
  cert_issuer = CERT_FindCertIssuer(cert,PR_Now(),certUsageObjectSigner);

  proto_win = SSL_RevealPinArg(sock);
  issuer = PK11_FindCertFromNickname(issuer_nickname, proto_win);

  if((!cert_issuer) || (!issuer))
    res = SECFailure;
  else if(SECITEM_CompareItem(&cert_issuer->derCert,
                              &issuer->derCert)!=SECEqual)
    res = SECFailure;

  CERT_DestroyCertificate(cert);
  CERT_DestroyCertificate(issuer);
  CERT_DestroyCertificate(cert_issuer);
  return res;
}
コード例 #5
0
ファイル: mar_sign.c プロジェクト: Flatta/LibreOffice-core
/**
 * Obtains a signing context.
 *
 * @param  ctx A pointer to the signing context to fill
 * @return 0 on success
 *         -1 on error
*/
int
NSSSignBegin(const char *certName,
             SGNContext **ctx,
             SECKEYPrivateKey **privKey,
             CERTCertificate **cert,
             uint32_t *signatureLength)
{
  secuPWData pwdata = { PW_NONE, 0 };
  if (!certName || !ctx || !privKey || !cert || !signatureLength) {
    fprintf(stderr, "ERROR: Invalid parameter passed to NSSSignBegin\n");
    return -1;
  }

  /* Get the cert and embedded public key out of the database */
  *cert = PK11_FindCertFromNickname(certName, &pwdata);
  if (!*cert) {
    fprintf(stderr, "ERROR: Could not find cert from nickname\n");
    return -1;
  }

  /* Get the private key out of the database */
  *privKey = PK11_FindKeyByAnyCert(*cert, &pwdata);
  if (!*privKey) {
    fprintf(stderr, "ERROR: Could not find private key\n");
    return -1;
  }

  *signatureLength = PK11_SignatureLen(*privKey);

  if (*signatureLength > BLOCKSIZE) {
    fprintf(stderr,
            "ERROR: Program must be compiled with a larger block size"
            " to support signing with signatures this large: %u.\n",
            *signatureLength);
    return -1;
  }

  /* Check that the key length is large enough for our requirements */
  if (*signatureLength < XP_MIN_SIGNATURE_LEN_IN_BYTES) {
    fprintf(stderr, "ERROR: Key length must be >= %d bytes\n",
            XP_MIN_SIGNATURE_LEN_IN_BYTES);
    return -1;
  }

  *ctx = SGN_NewContext (SEC_OID_ISO_SHA1_WITH_RSA_SIGNATURE, *privKey);
  if (!*ctx) {
    fprintf(stderr, "ERROR: Could not create signature context\n");
    return -1;
  }

  if (SGN_Begin(*ctx) != SECSuccess) {
    fprintf(stderr, "ERROR: Could not begin signature\n");
    return -1;
  }

  return 0;
}
コード例 #6
0
ファイル: certgen.c プロジェクト: AOSC-Dev/nss-purified
/***********************************************************************
 *
 * G e n e r a t e C e r t
 *
 * Runs the whole process of creating a new cert, getting info from the
 * user, etc.
 */
int
GenerateCert(char *nickname, int keysize, char *token)
{
    CERTCertDBHandle * db;
    CERTCertificate * cert;
    char	*subject;
    unsigned long	serial;
    char	stdinbuf[160];

    /* Print warning about having the browser open */
    PR_fprintf(PR_STDOUT /*always go to console*/,
        "\nWARNING: Performing this operation while the browser is running could cause"
        "\ncorruption of your security databases. If the browser is currently running,"
        "\nyou should exit the browser before continuing this operation. Enter "
        "\n\"y\" to continue, or anything else to abort: ");
    pr_fgets(stdinbuf, 160, PR_STDIN);
    PR_fprintf(PR_STDOUT, "\n");
    if (tolower(stdinbuf[0]) != 'y') {
	PR_fprintf(errorFD, "Operation aborted at user's request.\n");
	errorCount++;
	return - 1;
    }

    db = CERT_GetDefaultCertDB();
    if (!db) {
	FatalError("Unable to open certificate database");
    }

    if (PK11_FindCertFromNickname(nickname, &pwdata)) {
	PR_fprintf(errorFD,
	    "ERROR: Certificate with nickname \"%s\" already exists in database. You\n"
	    "must choose a different nickname.\n", nickname);
	errorCount++;
	exit(ERRX);
    }

    LL_L2UI(serial, PR_Now());

    subject = GetSubjectFromUser(serial);

    cert = GenerateSelfSignedObjectSigningCert(nickname, db, subject,
         		serial, keysize, token);

    if (cert) {
	output_ca_cert(cert, db);
	CERT_DestroyCertificate(cert);
    }

    PORT_Free(subject);
    return 0;
}
コード例 #7
0
ファイル: nss.c プロジェクト: heavilessrose/my-sync
/**
 *
 * Callback to pick the SSL client certificate.
 */
static SECStatus SelectClientCert(void *arg, PRFileDesc *sock,
                                  struct CERTDistNamesStr *caNames,
                                  struct CERTCertificateStr **pRetCert,
                                  struct SECKEYPrivateKeyStr **pRetKey)
{
  SECKEYPrivateKey *privKey;
  struct ssl_connect_data *connssl = (struct ssl_connect_data *) arg;
  char *nickname = connssl->client_nickname;
  void *proto_win = NULL;
  SECStatus secStatus = SECFailure;
  PK11SlotInfo *slot;
  (void)caNames;

  proto_win = SSL_RevealPinArg(sock);

  if(!nickname)
    return secStatus;

  connssl->client_cert = PK11_FindCertFromNickname(nickname, proto_win);
  if(connssl->client_cert) {

    if(!strncmp(nickname, "PEM Token", 9)) {
      CK_SLOT_ID slotID = 1; /* hardcoded for now */
      char slotname[SLOTSIZE];
      snprintf(slotname, SLOTSIZE, "PEM Token #%ld", slotID);
      slot = PK11_FindSlotByName(slotname);
      privKey = PK11_FindPrivateKeyFromCert(slot, connssl->client_cert, NULL);
      PK11_FreeSlot(slot);
      if(privKey) {
        secStatus = SECSuccess;
      }
    }
    else {
      privKey = PK11_FindKeyByAnyCert(connssl->client_cert, proto_win);
      if(privKey)
        secStatus = SECSuccess;
    }
  }

  if(secStatus == SECSuccess) {
    *pRetCert = connssl->client_cert;
    *pRetKey = privKey;
  }
  else {
    if(connssl->client_cert)
      CERT_DestroyCertificate(connssl->client_cert);
    connssl->client_cert = NULL;
  }

  return secStatus;
}
コード例 #8
0
ファイル: SslSocket.cpp プロジェクト: ChugR/qpid-cpp
int SslSocket::listen(const SocketAddress& sa, int backlog) const
{
    //get certificate and key (is this the correct way?)
    std::string cName( (certname == "") ? "localhost.localdomain" : certname);
    CERTCertificate *cert = PK11_FindCertFromNickname(const_cast<char*>(cName.c_str()), 0);
    if (!cert) throw Exception(QPID_MSG("Failed to load certificate '" << cName << "'"));
    SECKEYPrivateKey *key = PK11_FindKeyByAnyCert(cert, 0);
    if (!key) throw Exception(QPID_MSG("Failed to retrieve private key from certificate"));
    NSS_CHECK(SSL_ConfigSecureServer(prototype, cert, key, NSS_FindCertKEAType(cert)));
    SECKEY_DestroyPrivateKey(key);
    CERT_DestroyCertificate(cert);

    return BSDSocket::listen(sa, backlog);
}
コード例 #9
0
ファイル: qnetd-instance.c プロジェクト: credativ/corosync
int
qnetd_instance_init_certs(struct qnetd_instance *instance)
{

	instance->server.cert = PK11_FindCertFromNickname(
	    instance->advanced_settings->cert_nickname, NULL);
	if (instance->server.cert == NULL) {
		return (-1);
	}

	instance->server.private_key = PK11_FindKeyByAnyCert(instance->server.cert, NULL);
	if (instance->server.private_key == NULL) {
		return (-1);
	}

	return (0);
}
コード例 #10
0
ファイル: nss.c プロジェクト: CedricCabessa/curl-android
static CURLcode nss_load_cert(struct ssl_connect_data *ssl,
                              const char *filename, PRBool cacert)
{
  CURLcode err = (cacert)
    ? CURLE_SSL_CACERT_BADFILE
    : CURLE_SSL_CERTPROBLEM;

#ifdef HAVE_PK11_CREATEGENERICOBJECT
  /* libnsspem.so leaks memory if the requested file does not exist.  For more
   * details, go to <https://bugzilla.redhat.com/734760>. */
  if(is_file(filename))
    err = nss_create_object(ssl, CKO_CERTIFICATE, filename, cacert);

  if(CURLE_OK == err && !cacert) {
    /* we have successfully loaded a client certificate */
    CERTCertificate *cert;
    char *nickname = NULL;
    char *n = strrchr(filename, '/');
    if(n)
      n++;

    /* The following undocumented magic helps to avoid a SIGSEGV on call
     * of PK11_ReadRawAttribute() from SelectClientCert() when using an
     * immature version of libnsspem.so.  For more details, go to
     * <https://bugzilla.redhat.com/733685>. */
    nickname = aprintf("PEM Token #1:%s", n);
    if(nickname) {
      cert = PK11_FindCertFromNickname(nickname, NULL);
      if(cert)
        CERT_DestroyCertificate(cert);

      free(nickname);
    }
  }
#endif

  return err;
}
コード例 #11
0
ファイル: SslSocket.cpp プロジェクト: KeithLatteri/awips2
int SslSocket::listen(uint16_t port, int backlog, const std::string& certName, bool clientAuth) const
{
    //configure prototype socket:
    prototype = SSL_ImportFD(0, PR_NewTCPSocket());
    if (clientAuth) {
        NSS_CHECK(SSL_OptionSet(prototype, SSL_REQUEST_CERTIFICATE, PR_TRUE));
        NSS_CHECK(SSL_OptionSet(prototype, SSL_REQUIRE_CERTIFICATE, PR_TRUE));
    }

    //get certificate and key (is this the correct way?)
    CERTCertificate *cert = PK11_FindCertFromNickname(const_cast<char*>(certName.c_str()), 0);
    if (!cert) throw Exception(QPID_MSG("Failed to load certificate '" << certName << "'"));
    SECKEYPrivateKey *key = PK11_FindKeyByAnyCert(cert, 0);
    if (!key) throw Exception(QPID_MSG("Failed to retrieve private key from certificate"));
    NSS_CHECK(SSL_ConfigSecureServer(prototype, cert, key, NSS_FindCertKEAType(cert)));
    SECKEY_DestroyPrivateKey(key);
    CERT_DestroyCertificate(cert);

    //bind and listen
    const int& socket = impl->fd;
    int yes=1;
    QPID_POSIX_CHECK(setsockopt(socket,SOL_SOCKET,SO_REUSEADDR,&yes,sizeof(yes)));
    struct sockaddr_in name;
    name.sin_family = AF_INET;
    name.sin_port = htons(port);
    name.sin_addr.s_addr = 0;
    if (::bind(socket, (struct sockaddr*)&name, sizeof(name)) < 0)
        throw Exception(QPID_MSG("Can't bind to port " << port << ": " << strError(errno)));
    if (::listen(socket, backlog) < 0)
        throw Exception(QPID_MSG("Can't listen on port " << port << ": " << strError(errno)));
    
    socklen_t namelen = sizeof(name);
    if (::getsockname(socket, (struct sockaddr*)&name, &namelen) < 0)
        throw QPID_POSIX_ERROR(errno);

    return ntohs(name.sin_port);
}
コード例 #12
0
ファイル: stanpcertdb.c プロジェクト: MekliCZ/positron
CERTCertificate *
CERT_FindCertByNickname(CERTCertDBHandle *handle, const char *nickname)
{
    NSSCryptoContext *cc;
    NSSCertificate *c, *ct;
    CERTCertificate *cert;
    NSSUsage usage;
    usage.anyUsage = PR_TRUE;
    cc = STAN_GetDefaultCryptoContext();
    ct = NSSCryptoContext_FindBestCertificateByNickname(cc, nickname, NULL,
                                                        &usage, NULL);
    cert = PK11_FindCertFromNickname(nickname, NULL);
    c = NULL;
    if (cert) {
        c = get_best_temp_or_perm(ct, STAN_GetNSSCertificate(cert));
        CERT_DestroyCertificate(cert);
        if (ct) {
            CERT_DestroyCertificate(STAN_GetCERTCertificateOrRelease(ct));
        }
    } else {
        c = ct;
    }
    return c ? STAN_GetCERTCertificateOrRelease(c) : NULL;
}
コード例 #13
0
CERTCertificate *
CERT_FindCertByNicknameOrEmailAddr(CERTCertDBHandle *handle, const char *name)
{
    NSSCryptoContext *cc;
    NSSCertificate *c, *ct;
    CERTCertificate *cert;
    NSSUsage usage;

    if (NULL == name) {
        PORT_SetError(SEC_ERROR_INVALID_ARGS);
	return NULL;
    }
    usage.anyUsage = PR_TRUE;
    cc = STAN_GetDefaultCryptoContext();
    ct = NSSCryptoContext_FindBestCertificateByNickname(cc, name, 
                                                       NULL, &usage, NULL);
    if (!ct && PORT_Strchr(name, '@') != NULL) {
        char* lowercaseName = CERT_FixupEmailAddr(name);
        if (lowercaseName) {
	    ct = NSSCryptoContext_FindBestCertificateByEmail(cc, lowercaseName, 
							    NULL, &usage, NULL);
            PORT_Free(lowercaseName);
        }
    }
    cert = PK11_FindCertFromNickname(name, NULL);
    if (cert) {
	c = get_best_temp_or_perm(ct, STAN_GetNSSCertificate(cert));
	CERT_DestroyCertificate(cert);
	if (ct) {
	    CERT_DestroyCertificate(STAN_GetCERTCertificateOrRelease(ct));
	}
    } else {
	c = ct;
    }
    return c ? STAN_GetCERTCertificateOrRelease(c) : NULL;
}
コード例 #14
0
ファイル: mar.c プロジェクト: Jar-win/Waterfox
int main(int argc, char **argv) {
  char *NSSConfigDir = NULL;
  const char *certNames[MAX_SIGNATURES];
  char *MARChannelID = MAR_CHANNEL_ID;
  char *productVersion = MOZ_APP_VERSION;
  uint32_t k;
  int rv = -1;
  uint32_t certCount = 0;
  int32_t sigIndex = -1;

#if !defined(NO_SIGN_VERIFY)
  uint32_t fileSizes[MAX_SIGNATURES];
  const uint8_t* certBuffers[MAX_SIGNATURES];
  char* DERFilePaths[MAX_SIGNATURES];
#if (!defined(XP_WIN) && !defined(XP_MACOSX)) || defined(MAR_NSS)
  CERTCertificate* certs[MAX_SIGNATURES];
#endif
#endif

  memset((void*)certNames, 0, sizeof(certNames));
#if defined(XP_WIN) && !defined(MAR_NSS) && !defined(NO_SIGN_VERIFY)
  memset((void*)certBuffers, 0, sizeof(certBuffers));
#endif
#if !defined(NO_SIGN_VERIFY) && ((!defined(MAR_NSS) && defined(XP_WIN)) || \
                                 defined(XP_MACOSX))
  memset(DERFilePaths, 0, sizeof(DERFilePaths));
  memset(fileSizes, 0, sizeof(fileSizes));
#endif

  if (argc > 1 && 0 == strcmp(argv[1], "--version")) {
    print_version();
    return 0;
  }

  if (argc < 3) {
    print_usage();
    return -1;
  }

  while (argc > 0) {
    if (argv[1][0] == '-' && (argv[1][1] == 'c' || 
        argv[1][1] == 't' || argv[1][1] == 'x' || 
        argv[1][1] == 'v' || argv[1][1] == 's' ||
        argv[1][1] == 'i' || argv[1][1] == 'T' ||
        argv[1][1] == 'r' || argv[1][1] == 'X' ||
        argv[1][1] == 'I')) {
      break;
    /* -C workingdirectory */
    } else if (argv[1][0] == '-' && argv[1][1] == 'C') {
      if (chdir(argv[2]) != 0) {
        return -1;
      }
      argv += 2;
      argc -= 2;
    } 
#if !defined(NO_SIGN_VERIFY) && ((!defined(MAR_NSS) && defined(XP_WIN)) || \
                                 defined(XP_MACOSX))
    /* -D DERFilePath, also matches -D[index] DERFilePath
       We allow an index for verifying to be symmetric
       with the import and export command line arguments. */
    else if (argv[1][0] == '-' &&
             argv[1][1] == 'D' &&
             (argv[1][2] == (char)('0' + certCount) || argv[1][2] == '\0')) {
      if (certCount >= MAX_SIGNATURES) {
        print_usage();
        return -1;
      }
      DERFilePaths[certCount++] = argv[2];
      argv += 2;
      argc -= 2;
    }
#endif
    /* -d NSSConfigdir */
    else if (argv[1][0] == '-' && argv[1][1] == 'd') {
      NSSConfigDir = argv[2];
      argv += 2;
      argc -= 2;
     /* -n certName, also matches -n[index] certName
        We allow an index for verifying to be symmetric
        with the import and export command line arguments. */
    } else if (argv[1][0] == '-' &&
               argv[1][1] == 'n' &&
               (argv[1][2] == (char)('0' + certCount) ||
                argv[1][2] == '\0' ||
                !strcmp(argv[2], "-X") ||
                !strcmp(argv[2], "-I"))) {
      if (certCount >= MAX_SIGNATURES) {
        print_usage();
        return -1;
      }
      certNames[certCount++] = argv[2];
      if (strlen(argv[1]) > 2 &&
          (!strcmp(argv[2], "-X") || !strcmp(argv[2], "-I")) &&
          argv[1][2] >= '0' && argv[1][2] <= '9') {
        sigIndex = argv[1][2] - '0';
        argv++;
        argc--;
      } else {
        argv += 2;
        argc -= 2;
      }
    /* MAR channel ID */
    } else if (argv[1][0] == '-' && argv[1][1] == 'H') {
      MARChannelID = argv[2];
      argv += 2;
      argc -= 2;
    /* Product Version */
    } else if (argv[1][0] == '-' && argv[1][1] == 'V') {
      productVersion = argv[2];
      argv += 2;
      argc -= 2;
    }
    else {
      print_usage();
      return -1;
    }
  }

  if (argv[1][0] != '-') {
    print_usage();
    return -1;
  }

  switch (argv[1][1]) {
  case 'c': {
    struct ProductInformationBlock infoBlock;
    infoBlock.MARChannelID = MARChannelID;
    infoBlock.productVersion = productVersion;
    return mar_create(argv[2], argc - 3, argv + 3, &infoBlock);
  }
  case 'i': {
    struct ProductInformationBlock infoBlock;
    infoBlock.MARChannelID = MARChannelID;
    infoBlock.productVersion = productVersion;
    return refresh_product_info_block(argv[2], &infoBlock);
  }
  case 'T': {
    struct ProductInformationBlock infoBlock;
    uint32_t numSignatures, numAdditionalBlocks;
    int hasSignatureBlock, hasAdditionalBlock;
    if (!get_mar_file_info(argv[2], 
                           &hasSignatureBlock,
                           &numSignatures,
                           &hasAdditionalBlock, 
                           NULL, &numAdditionalBlocks)) {
      if (hasSignatureBlock) {
        printf("Signature block found with %d signature%s\n", 
               numSignatures, 
               numSignatures != 1 ? "s" : "");
      }
      if (hasAdditionalBlock) {
        printf("%d additional block%s found:\n", 
               numAdditionalBlocks,
               numAdditionalBlocks != 1 ? "s" : "");
      }

      rv = read_product_info_block(argv[2], &infoBlock);
      if (!rv) {
        printf("  - Product Information Block:\n");
        printf("    - MAR channel name: %s\n"
               "    - Product version: %s\n",
               infoBlock.MARChannelID,
               infoBlock.productVersion);
        free((void *)infoBlock.MARChannelID);
        free((void *)infoBlock.productVersion);
      }
     }
    printf("\n");
    /* The fall through from 'T' to 't' is intentional */
  }
  case 't':
    return mar_test(argv[2]);

  /* Extract a MAR file */
  case 'x':
    return mar_extract(argv[2]);

#ifndef NO_SIGN_VERIFY
  /* Extract a MAR signature */
  case 'X':
    if (sigIndex == -1) {
      fprintf(stderr, "ERROR: Signature index was not passed.\n");
      return -1;
    }
    if (sigIndex >= MAX_SIGNATURES || sigIndex < -1) {
      fprintf(stderr, "ERROR: Signature index is out of range: %d.\n",
              sigIndex);
      return -1;
    }
    return extract_signature(argv[2], sigIndex, argv[3]);

  /* Import a MAR signature */
  case 'I':
    if (sigIndex == -1) {
      fprintf(stderr, "ERROR: signature index was not passed.\n");
      return -1;
    }
    if (sigIndex >= MAX_SIGNATURES || sigIndex < -1) {
      fprintf(stderr, "ERROR: Signature index is out of range: %d.\n",
              sigIndex);
      return -1;
    }
    if (argc < 5) {
      print_usage();
      return -1;
    }
    return import_signature(argv[2], sigIndex, argv[3], argv[4]);

  case 'v':
    if (certCount == 0) {
      print_usage();
      return -1;
    }

#if (!defined(XP_WIN) && !defined(XP_MACOSX)) || defined(MAR_NSS)
    if (!NSSConfigDir || certCount == 0) {
      print_usage();
      return -1;
    }

    if (NSSInitCryptoContext(NSSConfigDir)) {
      fprintf(stderr, "ERROR: Could not initialize crypto library.\n");
      return -1;
    }
#endif

    rv = 0;
    for (k = 0; k < certCount; ++k) {
#if (defined(XP_WIN) || defined(XP_MACOSX)) && !defined(MAR_NSS)
      rv = mar_read_entire_file(DERFilePaths[k], MAR_MAX_CERT_SIZE,
                                &certBuffers[k], &fileSizes[k]);
#else
      /* It is somewhat circuitous to look up a CERTCertificate and then pass
       * in its DER encoding just so we can later re-create that
       * CERTCertificate to extract the public key out of it. However, by doing
       * things this way, we maximize the reuse of the mar_verify_signatures
       * function and also we keep the control flow as similar as possible
       * between programs and operating systems, at least for the functions
       * that are critically important to security.
       */
      certs[k] = PK11_FindCertFromNickname(certNames[k], NULL);
      if (certs[k]) {
        certBuffers[k] = certs[k]->derCert.data;
        fileSizes[k] = certs[k]->derCert.len;
      } else {
        rv = -1;
      }
#endif
      if (rv) {
        fprintf(stderr, "ERROR: could not read file %s", DERFilePaths[k]);
        break;
      }
    }

    if (!rv) {
      MarFile *mar = mar_open(argv[2]);
      if (mar) {
        rv = mar_verify_signatures(mar, certBuffers, fileSizes, certCount);
        mar_close(mar);
      } else {
        fprintf(stderr, "ERROR: Could not open MAR file.\n");
        rv = -1;
      }
    }
    for (k = 0; k < certCount; ++k) {
#if (defined(XP_WIN) || defined(XP_MACOSX)) && !defined(MAR_NSS)
      free((void*)certBuffers[k]);
#else
      /* certBuffers[k] is owned by certs[k] so don't free it */
      CERT_DestroyCertificate(certs[k]);
#endif
    }
    if (rv) {
      /* Determine if the source MAR file has the new fields for signing */
      int hasSignatureBlock;
      if (get_mar_file_info(argv[2], &hasSignatureBlock, 
                            NULL, NULL, NULL, NULL)) {
        fprintf(stderr, "ERROR: could not determine if MAR is old or new.\n");
      } else if (!hasSignatureBlock) {
        fprintf(stderr, "ERROR: The MAR file is in the old format so has"
                        " no signature to verify.\n");
      }
      return -1;
    }
    return 0;

  case 's':
    if (!NSSConfigDir || certCount == 0 || argc < 4) {
      print_usage();
      return -1;
    }
    return mar_repackage_and_sign(NSSConfigDir, certNames, certCount,
                                  argv[2], argv[3]);

  case 'r':
    return strip_signature_block(argv[2], argv[3]);
#endif /* endif NO_SIGN_VERIFY disabled */

  default:
    print_usage();
    return -1;
  }
}
コード例 #15
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++;
  }
}
コード例 #16
0
ファイル: sign.c プロジェクト: Akin-Net/mozilla-central
/*********************************************************************
 *
 * c r e a t e _ p k 7
 */
static int	
create_pk7 (char *dir, char *keyName, int *keyType)
{
    int	status = 0;
    char	*file_ext;

    CERTCertificate * cert;
    CERTCertDBHandle * db;

    FILE * in, *out;

    char	sf_file [FNSIZE];
    char	pk7_file [FNSIZE];

    /* open cert database */
    db = CERT_GetDefaultCertDB();

    if (db == NULL)
	return - 1;

    /* find cert */
    /*cert = CERT_FindCertByNicknameOrEmailAddr(db, keyName);*/
    cert = PK11_FindCertFromNickname(keyName, &pwdata);

    if (cert == NULL) {
	SECU_PrintError ( PROGRAM_NAME,
	    "Cannot find the cert \"%s\"", keyName);
	return -1;
    }


    /* determine the key type, which sets the extension for pkcs7 object */

    *keyType = jar_find_key_type (cert);
    file_ext = (*keyType == dsaKey) ? "dsa" : "rsa";

    sprintf (sf_file, "%s/META-INF/%s.sf", dir, base);
    sprintf (pk7_file, "%s/META-INF/%s.%s", dir, base, file_ext);

    if ((in = fopen (sf_file, "rb")) == NULL) {
	PR_fprintf(errorFD, "%s: Can't open %s for reading\n", PROGRAM_NAME,
	     sf_file);
	errorCount++;
	exit (ERRX);
    }

    if ((out = fopen (pk7_file, "wb")) == NULL) {
	PR_fprintf(errorFD, "%s: Can't open %s for writing\n", PROGRAM_NAME,
	     sf_file);
	errorCount++;
	exit (ERRX);
    }

    status = SignFile (out, in, cert);

    CERT_DestroyCertificate (cert);
    fclose (in);
    fclose (out);

    if (status) {
	PR_fprintf(errorFD, "%s: PROBLEM signing data (%s)\n",
	    PROGRAM_NAME, SECU_ErrorString ((int16) PORT_GetError()));
	errorCount++;
	return - 1;
    }

    return 0;
}
コード例 #17
0
ファイル: list.c プロジェクト: MichaelKohler/gecko-dev
/*********************************************************************
 *
 * L i s t C e r t s
 */
int
ListCerts(char *key, int list_certs)
{
    int failed = 0;
    SECStatus rv;
    char *ugly_list;
    CERTCertDBHandle *db;

    CERTCertificate *cert;
    CERTVerifyLog errlog;

    errlog.arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
    if (errlog.arena == NULL) {
        out_of_memory();
    }
    errlog.head = NULL;
    errlog.tail = NULL;
    errlog.count = 0;

    ugly_list = PORT_ZAlloc(16);

    if (ugly_list == NULL) {
        out_of_memory();
    }

    *ugly_list = 0;

    db = CERT_GetDefaultCertDB();

    if (list_certs == 2) {
        PR_fprintf(outputFD, "\nS Certificates\n");
        PR_fprintf(outputFD, "- ------------\n");
    } else {
        PR_fprintf(outputFD, "\nObject signing certificates\n");
        PR_fprintf(outputFD, "---------------------------------------\n");
    }

    num_trav_certs = 0;

    /* Traverse ALL tokens in all slots, authenticating to them all */
    rv = PK11_TraverseSlotCerts(cert_trav_callback, (void *)&list_certs,
                                &pwdata);

    if (rv) {
        PR_fprintf(outputFD, "**Traverse of ALL slots & tokens failed**\n");
        return -1;
    }

    if (num_trav_certs == 0) {
        PR_fprintf(outputFD,
                   "You don't appear to have any object signing certificates.\n");
    }

    if (list_certs == 2) {
        PR_fprintf(outputFD, "- ------------\n");
    } else {
        PR_fprintf(outputFD, "---------------------------------------\n");
    }

    if (list_certs == 1) {
        PR_fprintf(outputFD,
                   "For a list including CA's, use \"%s -L\"\n", PROGRAM_NAME);
    }

    if (list_certs == 2) {
        PR_fprintf(outputFD,
                   "Certificates that can be used to sign objects have *'s to "
                   "their left.\n");
    }

    if (key) {
        /* Do an analysis of the given cert */

        cert = PK11_FindCertFromNickname(key, &pwdata);

        if (cert) {
            PR_fprintf(outputFD,
                       "\nThe certificate with nickname \"%s\" was found:\n",
                       cert->nickname);
            PR_fprintf(outputFD, "\tsubject name: %s\n", cert->subjectName);
            PR_fprintf(outputFD, "\tissuer name: %s\n", cert->issuerName);

            PR_fprintf(outputFD, "\n");

            rv = CERT_CertTimesValid(cert);
            if (rv != SECSuccess) {
                PR_fprintf(outputFD, "**This certificate is expired**\n");
            } else {
                PR_fprintf(outputFD, "This certificate is not expired.\n");
            }

            rv = CERT_VerifyCert(db, cert, PR_TRUE,
                                 certUsageObjectSigner, PR_Now(), &pwdata, &errlog);

            if (rv != SECSuccess) {
                failed = 1;
                if (errlog.count > 0) {
                    PR_fprintf(outputFD,
                               "**Certificate validation failed for the "
                               "following reason(s):**\n");
                } else {
                    PR_fprintf(outputFD, "**Certificate validation failed**");
                }
            } else {
                PR_fprintf(outputFD, "This certificate is valid.\n");
            }
            displayVerifyLog(&errlog);

        } else {
            failed = 1;
            PR_fprintf(outputFD,
                       "The certificate with nickname \"%s\" was NOT FOUND\n", key);
        }
    }

    if (errlog.arena != NULL) {
        PORT_FreeArena(errlog.arena, PR_FALSE);
    }

    if (failed) {
        return -1;
    }
    return 0;
}
コード例 #18
0
ファイル: vcard_emul_nss.c プロジェクト: AjayMashi/x-tier
VCardEmulError
vcard_emul_init(const VCardEmulOptions *options)
{
    SECStatus rv;
    PRBool ret, has_readers = PR_FALSE;
    VReader *vreader;
    VReaderEmul *vreader_emul;
    SECMODListLock *module_lock;
    SECMODModuleList *module_list;
    SECMODModuleList *mlp;
    int i;

    if (vcard_emul_init_called) {
        return VCARD_EMUL_INIT_ALREADY_INITED;
    }
    vcard_emul_init_called = 1;
    vreader_init();
    vevent_queue_init();

    if (options == NULL) {
        options = &default_options;
    }

    /* first initialize NSS */
    if (options->nss_db) {
        rv = NSS_Init(options->nss_db);
    } else {
        gchar *path;
#ifndef _WIN32
        path = g_strdup("/etc/pki/nssdb");
#else
        if (g_get_system_config_dirs() == NULL ||
            g_get_system_config_dirs()[0] == NULL) {
            return VCARD_EMUL_FAIL;
        }

        path = g_build_filename(
            g_get_system_config_dirs()[0], "pki", "nssdb", NULL);
#endif

        rv = NSS_Init(path);
        g_free(path);
    }
    if (rv != SECSuccess) {
        return VCARD_EMUL_FAIL;
    }
    /* Set password callback function */
    PK11_SetPasswordFunc(vcard_emul_get_password);

    /* set up soft cards emulated by software certs rather than physical cards
     * */
    for (i = 0; i < options->vreader_count; i++) {
        int j;
        int cert_count;
        unsigned char **certs;
        int *cert_len;
        VCardKey **keys;
        PK11SlotInfo *slot;

        slot = PK11_FindSlotByName(options->vreader[i].name);
        if (slot == NULL) {
            continue;
        }
        vreader_emul = vreader_emul_new(slot, options->vreader[i].card_type,
                                        options->vreader[i].type_params);
        vreader = vreader_new(options->vreader[i].vname, vreader_emul,
                              vreader_emul_delete);
        vreader_add_reader(vreader);
        cert_count = options->vreader[i].cert_count;

        ret = vcard_emul_alloc_arrays(&certs, &cert_len, &keys,
                                      options->vreader[i].cert_count);
        if (ret == PR_FALSE) {
            continue;
        }
        cert_count = 0;
        for (j = 0; j < options->vreader[i].cert_count; j++) {
            /* we should have a better way of identifying certs than by
             * nickname here */
            CERTCertificate *cert = PK11_FindCertFromNickname(
                                        options->vreader[i].cert_name[j],
                                        NULL);
            if (cert == NULL) {
                continue;
            }
            certs[cert_count] = cert->derCert.data;
            cert_len[cert_count] = cert->derCert.len;
            keys[cert_count] = vcard_emul_make_key(slot, cert);
            /* this is safe because the key is still holding a cert reference */
            CERT_DestroyCertificate(cert);
            cert_count++;
        }
        if (cert_count) {
            VCard *vcard = vcard_emul_make_card(vreader, certs, cert_len,
                                                keys, cert_count);
            vreader_insert_card(vreader, vcard);
            vcard_emul_init_series(vreader, vcard);
            /* allow insertion and removal of soft cards */
            vreader_emul->saved_vcard = vcard_reference(vcard);
            vcard_free(vcard);
            vreader_free(vreader);
            has_readers = PR_TRUE;
        }
        g_free(certs);
        g_free(cert_len);
        g_free(keys);
    }

    /* if we aren't suppose to use hw, skip looking up hardware tokens */
    if (!options->use_hw) {
        nss_emul_init = has_readers;
        return has_readers ? VCARD_EMUL_OK : VCARD_EMUL_FAIL;
    }

    /* make sure we have some PKCS #11 module loaded */
    module_lock = SECMOD_GetDefaultModuleListLock();
    module_list = SECMOD_GetDefaultModuleList();
    SECMOD_GetReadLock(module_lock);
    for (mlp = module_list; mlp; mlp = mlp->next) {
        SECMODModule *module = mlp->module;
        if (module_has_removable_hw_slots(module)) {
            break;
        }
    }
    SECMOD_ReleaseReadLock(module_lock);

    /* now examine all the slots, finding which should be readers */
    /* We should control this with options. For now we mirror out any
     * removable hardware slot */
    default_card_type = options->hw_card_type;
    default_type_params = g_strdup(options->hw_type_params);

    SECMOD_GetReadLock(module_lock);
    for (mlp = module_list; mlp; mlp = mlp->next) {
        SECMODModule *module = mlp->module;

        /* Ignore the internal module */
        if (module == NULL || module == SECMOD_GetInternalModule()) {
            continue;
        }

        for (i = 0; i < module->slotCount; i++) {
            PK11SlotInfo *slot = module->slots[i];

            /* only map removable HW slots */
            if (slot == NULL || !PK11_IsRemovable(slot) || !PK11_IsHW(slot)) {
                continue;
            }
            if (strcmp("E-Gate 0 0", PK11_GetSlotName(slot)) == 0) {
                /*
                 * coolkey <= 1.1.0-20 emulates this reader if it can't find
                 * any hardware readers. This causes problems, warn user of
                 * problems.
                 */
                fprintf(stderr, "known bad coolkey version - see "
                        "https://bugzilla.redhat.com/show_bug.cgi?id=802435\n");
                continue;
            }
            vreader_emul = vreader_emul_new(slot, options->hw_card_type,
                                            options->hw_type_params);
            vreader = vreader_new(PK11_GetSlotName(slot), vreader_emul,
                                  vreader_emul_delete);
            vreader_add_reader(vreader);

            if (PK11_IsPresent(slot)) {
                VCard *vcard;
                vcard = vcard_emul_mirror_card(vreader);
                vreader_insert_card(vreader, vcard);
                vcard_emul_init_series(vreader, vcard);
                vcard_free(vcard);
            }
        }
        vcard_emul_new_event_thread(module);
    }
    SECMOD_ReleaseReadLock(module_lock);
    nss_emul_init = PR_TRUE;

    return VCARD_EMUL_OK;
}
コード例 #19
0
ファイル: stanpcertdb.c プロジェクト: MekliCZ/positron
static CERTCertificate *
common_FindCertByNicknameOrEmailAddrForUsage(CERTCertDBHandle *handle,
                                             const char *name, PRBool anyUsage,
                                             SECCertUsage lookingForUsage)
{
    NSSCryptoContext *cc;
    NSSCertificate *c, *ct;
    CERTCertificate *cert = NULL;
    NSSUsage usage;
    CERTCertList *certlist;

    if (NULL == name) {
        PORT_SetError(SEC_ERROR_INVALID_ARGS);
        return NULL;
    }

    usage.anyUsage = anyUsage;

    if (!anyUsage) {
        usage.nss3lookingForCA = PR_FALSE;
        usage.nss3usage = lookingForUsage;
    }

    cc = STAN_GetDefaultCryptoContext();
    ct = NSSCryptoContext_FindBestCertificateByNickname(cc, name, NULL, &usage,
                                                        NULL);
    if (!ct && PORT_Strchr(name, '@') != NULL) {
        char *lowercaseName = CERT_FixupEmailAddr(name);
        if (lowercaseName) {
            ct = NSSCryptoContext_FindBestCertificateByEmail(
                cc, lowercaseName, NULL, &usage, NULL);
            PORT_Free(lowercaseName);
        }
    }

    if (anyUsage) {
        cert = PK11_FindCertFromNickname(name, NULL);
    } else {
        if (ct) {
            /* Does ct really have the required usage? */
            nssDecodedCert *dc;
            dc = nssCertificate_GetDecoding(ct);
            if (!dc->matchUsage(dc, &usage)) {
                CERT_DestroyCertificate(STAN_GetCERTCertificateOrRelease(ct));
                ct = NULL;
            }
        }

        certlist = PK11_FindCertsFromNickname(name, NULL);
        if (certlist) {
            SECStatus rv =
                CERT_FilterCertListByUsage(certlist, lookingForUsage, PR_FALSE);
            if (SECSuccess == rv &&
                !CERT_LIST_END(CERT_LIST_HEAD(certlist), certlist)) {
                cert = CERT_DupCertificate(CERT_LIST_HEAD(certlist)->cert);
            }
            CERT_DestroyCertList(certlist);
        }
    }

    if (cert) {
        c = get_best_temp_or_perm(ct, STAN_GetNSSCertificate(cert));
        CERT_DestroyCertificate(cert);
        if (ct) {
            CERT_DestroyCertificate(STAN_GetCERTCertificateOrRelease(ct));
        }
    } else {
        c = ct;
    }
    return c ? STAN_GetCERTCertificateOrRelease(c) : NULL;
}
コード例 #20
0
ファイル: sslc.c プロジェクト: Akin-Net/mozilla-central
int SetServerSecParms(struct ThreadData *td) {
  int rv;
  SECKEYPrivateKey *privKey;
  PRFileDesc *s;

  s = td->r;

  rv = SSL_Enable(s, SSL_SECURITY, 1);     /* Enable security on this socket */
  if (rv < 0)  return Error(10);

  if (SSLT_CLIENTAUTH_INITIAL == REP_ServerDoClientAuth) {
    rv = SSL_Enable(s, SSL_REQUEST_CERTIFICATE, 1);
    if (rv < 0)  return Error(11);
    }

  ClearCiphers(td);
  EnableCiphers(td);

  PK11_SetPasswordFunc(MyPWFunc);
  SSL_SetPKCS11PinArg(s,(void*) MyPWFunc);


  /* Find the certificates we are going to use from the database */


  /* Test for dummy certificate, which shouldn't exist */
  td->cert = PK11_FindCertFromNickname("XXXXXX_CERT_HARDCOREII_1024",NULL);
  if (td->cert != NULL) return Error(16);


  td->cert = NULL;
  if (NO_CERT != REP_ServerCert) {
    td->cert = PK11_FindCertFromNickname(nicknames[REP_ServerCert],NULL);
  }


  /* Note: if we're set to use NO_CERT as the server cert, then we'll
   * just essentially skip the rest of this (except for session ID cache setup)
   */

  
  if ( (NULL == td->cert)  && ( NO_CERT != REP_ServerCert )) {
    PR_fprintf(PR_STDERR, "Can't find certificate %s\n", nicknames[REP_ServerCert]);
    PR_fprintf(PR_STDERR, "Server: Seclib error: %s\n",
	       SECU_ErrorString ((int16) PR_GetError()));
    return Error(12);
  }
  

  if ((NO_CERT != REP_ServerCert)) {
    privKey = PK11_FindKeyByAnyCert(td->cert, NULL);
    if (privKey == NULL) {
      dbmsg((PR_STDERR, "Can't find key for this certificate\n"));
      return Error(13);
    }
    
    rv = SSL_ConfigSecureServer(s,td->cert,privKey, kt_rsa);
    if (rv != PR_SUCCESS) {
      dbmsg((PR_STDERR, "Can't config server error(%d) \n",rv));
      return Error(14);
    }
  }
  
  rv = SSL_ConfigServerSessionIDCache(10, 0, 0, ".");
  if (rv != 0) {    
    dbmsg((PR_STDERR, "Can't config server session ID cache (%d) \n",rv));
    return Error(15);
  }

  return 0;
}
コード例 #21
0
void OsTLSServerConnectionSocket::NSSInitSocket(PRFileDesc* pDescriptor, long timeoutInSecs, const char* szPassword)
{
    PRFileDesc         *tcpSocket = NULL;
    PRSocketOptionData      socketOption;
    PRStatus            prStatus;
    SECStatus           secStatus; 
//    PRIntn      hostenum;
//    PRNetAddr       addr;
	SSLKEAType  certKEA;

     tcpSocket = pDescriptor;
        if (socketDescriptor > OS_INVALID_SOCKET_DESCRIPTOR)
        {
            mpCert = PK11_FindCertFromNickname((char*)mCertNickname.data(), (char*)mCertPassword.data());
            if (mpCert == NULL)
            {
                mbInitializeFailed = true;
                goto TlsError;
            }

            unsigned char* szPwd = (unsigned char*) PR_Malloc(mCertPassword.length()+ 1);
            strncpy((char*)szPwd, mCertPassword.data(), mCertPassword.length()+1);
            mpPrivKey = PK11_FindKeyByAnyCert(mpCert, (char*)szPwd);
            if (mpPrivKey == NULL)
            {
                mbInitializeFailed = true;
                goto TlsError;
            }

            if (tcpSocket)
            {
                /* Make the socket blocking. */
                socketOption.option                 = PR_SockOpt_Nonblocking;
                socketOption.value.non_blocking = PR_FALSE;

                prStatus = PR_SetSocketOption(tcpSocket, &socketOption);
                if (prStatus != PR_SUCCESS)
                {
                    mbInitializeFailed = true;
                    goto TlsError;
                } 

                /* Import the socket into the SSL layer. */
                mpPRfd = SSL_ImportFD(NULL, tcpSocket);
                if (!mpPRfd)
                {
                    mbInitializeFailed = true;
                    goto TlsError;
                }

                /* Set configuration options. */
                secStatus = SSL_OptionSet(mpPRfd, SSL_SECURITY, PR_TRUE);
                if (secStatus != SECSuccess)
                {
                    mbInitializeFailed = true;
                    goto TlsError;
                }

	            secStatus = SSL_OptionSet(mpPRfd, SSL_HANDSHAKE_AS_SERVER, PR_TRUE);
	            if (secStatus != SECSuccess)
	            {
                    mbInitializeFailed = true;
                    goto TlsError;
	            }

                secStatus = SSL_AuthCertificateHook(mpPRfd,
                                                    (SSLAuthCertificate)OsTLS::AuthCertificate,
                                                    (void *)CERT_GetDefaultCertDB());
                if (secStatus != SECSuccess)
                {
                    mbInitializeFailed = true;
                    goto TlsError;
                }

                secStatus = SSL_BadCertHook(mpPRfd, 
                                            (SSLBadCertHandler)OsTLS::BadCertHandler, NULL);
                if (secStatus != SECSuccess)
                {
                    mbInitializeFailed = true;
                    goto TlsError;
                }

                secStatus = SSL_HandshakeCallback(mpPRfd, 
                                                  (SSLHandshakeCallback)OsTLS::HandshakeCallback,
                                                  (void*)this);
                if (secStatus != SECSuccess)
                {
                    mbInitializeFailed = true;
                    goto TlsError;
                }

                secStatus = SSL_SetPKCS11PinArg(mpPRfd, (void*)szPassword);
                if (secStatus != SECSuccess)
                {
                    mbInitializeFailed = true;
                    goto TlsError;
                }


	            certKEA = NSS_FindCertKEAType(mpCert);

	            secStatus = SSL_ConfigSecureServer(mpPRfd, mpCert, mpPrivKey, certKEA);
	            if (secStatus != SECSuccess)
	            {
                    mbInitializeFailed = true;
                    goto TlsError;
	            }
	            
                secStatus = SSL_ResetHandshake(mpPRfd, /* asServer */ PR_TRUE);
                if (secStatus != SECSuccess)
                {
                    mbInitializeFailed = true;
                    goto TlsError;
                }
	            
	            PR_Free(szPwd);
            }
            else
            {
                mIsConnected = FALSE;
                OsConnectionSocket::close();
                mbInitializeFailed = true;
            }
        }
TlsError:
        return;
}
コード例 #22
0
// Constructor
OsTLSServerSocket::OsTLSServerSocket(int connectionQueueSize,
                                     int serverPort,
                                     UtlString certNickname,
                                     UtlString certPassword,
                                     UtlString dbLocation,
                                     const UtlString bindAddress)
   : OsServerSocket(connectionQueueSize,serverPort, bindAddress.data(), false),
     mCertNickname(certNickname),
     mCertPassword(certPassword),
     mDbLocation(dbLocation),
     mpMozillaSSLSocket(NULL),
     mpCert(NULL),
     mpPrivKey(NULL),
     mTlsInitCode(TLS_INIT_SUCCESS)
{
    PRSocketOptionData      socketOption;
    PRStatus                prStatus;
    SECStatus secStatus;
    
    // import the newly created socket into NSS, and set the PRFileDesc.
    if (socketDescriptor > OS_INVALID_SOCKET_DESCRIPTOR)
    {
        /* Call the NSPR initialization routines. */
        PR_Init( PR_SYSTEM_THREAD, PR_PRIORITY_NORMAL, 1);

        /* Set the cert database password callback. */
        PK11_SetPasswordFunc(OsTLS::PasswordCallback);

        secStatus = NSS_Init(dbLocation.data());
        if (secStatus != SECSuccess)
        {
            mTlsInitCode = TLS_INIT_DATABASE_FAILURE;
            return ;
        }

        /* Set the policy for this server (REQUIRED - no default). */
        secStatus = NSS_SetExportPolicy();
        if (secStatus != SECSuccess)
        {
            mTlsInitCode = TLS_INIT_DATABASE_FAILURE;
            return ;
        }

        /* Get own certificate and private key. */
        mpCert = PK11_FindCertFromNickname((char*) certNickname.data(), (void*)certPassword.data());
        if (mpCert == NULL)
        {
            return ;
        }
            
        unsigned char* szPwd = (unsigned char*) PR_Malloc(certPassword.length()+ 1);
        strncpy((char*)szPwd, certPassword.data(), certPassword.length()+1);
        mpPrivKey = PK11_FindKeyByAnyCert(mpCert, (void*)szPwd);
        if (mpPrivKey == NULL)
        {
            mTlsInitCode = TLS_INIT_BAD_PASSWORD;
            // probably a wrong password
            return ;
        }

        /* Configure the server's cache for a multi-process application
        * using default timeout values (24 hrs) and directory location (/tmp). 
        */
        SSL_ConfigMPServerSIDCache(256, 0, 0, NULL);

        mpMozillaSSLSocket = PR_ImportTCPSocket(socketDescriptor);

        if (!mpMozillaSSLSocket)
        {
            mTlsInitCode = TLS_INIT_TCP_IMPORT_FAILURE;
        }
        else
        {
            /* Make the socket blocking. */
            socketOption.option                 = PR_SockOpt_Nonblocking;
            socketOption.value.non_blocking = PR_FALSE;

            prStatus = PR_SetSocketOption(mpMozillaSSLSocket, &socketOption);
            if (prStatus != PR_SUCCESS)
            {
                mTlsInitCode = TLS_INIT_NSS_FAILURE;
                return;
            }
            
            secStatus = SSL_CipherPrefSetDefault(SSL_RSA_WITH_NULL_MD5, PR_TRUE);
            if (secStatus != SECSuccess)
            {
                mTlsInitCode = TLS_INIT_NSS_FAILURE;
                return;
            }            
            
            PRNetAddr addr;
            /* Configure the network connection. */
            addr.inet.family = PR_AF_INET;
            addr.inet.ip     = inet_addr(bindAddress.data());
            addr.inet.port   = PR_htons(serverPort);

            /* Bind the address to the listener socket. */
            prStatus = PR_Bind(mpMozillaSSLSocket, &addr);
            if (prStatus != PR_SUCCESS)
            {
                mTlsInitCode = TLS_INIT_NSS_FAILURE;
                return;
            }
 
            /* Listen for connection on the socket.  The second argument is
            * the maximum size of the queue for pending connections.
            */
            prStatus = PR_Listen(mpMozillaSSLSocket, connectionQueueSize);
            if (prStatus != PR_SUCCESS)
            {
                mTlsInitCode = TLS_INIT_NSS_FAILURE;
                return;
            }
        }            
    }        
}
コード例 #23
0
ファイル: nss.c プロジェクト: zcopley/curl
static int nss_load_cert(struct ssl_connect_data *ssl,
                         const char *filename, PRBool cacert)
{
#ifdef HAVE_PK11_CREATEGENERICOBJECT
  /* All CA and trust objects go into slot 0. Other slots are used
   * for storing certificates.
   */
  const int slot_id = (cacert) ? 0 : 1;
#endif
  CERTCertificate *cert;
  char *nickname = NULL;
  char *n = NULL;

  /* If there is no slash in the filename it is assumed to be a regular
   * NSS nickname.
   */
  if(is_file(filename)) {
    n = strrchr(filename, '/');
    if(n)
      n++;
    if(!mod)
      return 1;
  }
  else {
    /* A nickname from the NSS internal database */
    if(cacert)
      return 0; /* You can't specify an NSS CA nickname this way */
    nickname = strdup(filename);
    if(!nickname)
      return 0;
    goto done;
  }

#ifdef HAVE_PK11_CREATEGENERICOBJECT
  nickname = aprintf("PEM Token #%d:%s", slot_id, n);
  if(!nickname)
    return 0;

  if(CURLE_OK != nss_create_object(ssl, CKO_CERTIFICATE, filename, cacert)) {
    free(nickname);
    return 0;
  }

#else
  /* We don't have PK11_CreateGenericObject but a file-based cert was passed
   * in. We need to fail.
   */
  return 0;
#endif

  done:
  /* Double-check that the certificate or nickname requested exists in
   * either the token or the NSS certificate database.
   */
  if(!cacert) {
    cert = PK11_FindCertFromNickname((char *)nickname, NULL);

    /* An invalid nickname was passed in */
    if(cert == NULL) {
      free(nickname);
      PR_SetError(SEC_ERROR_UNKNOWN_CERT, 0);
      return 0;
    }

    CERT_DestroyCertificate(cert);
  }

  free(nickname);

  return 1;
}
コード例 #24
0
ファイル: nss.c プロジェクト: 0w/moai-dev
static int nss_load_cert(struct ssl_connect_data *ssl,
                         const char *filename, PRBool cacert)
{
#ifdef HAVE_PK11_CREATEGENERICOBJECT
  CK_SLOT_ID slotID;
  PK11SlotInfo * slot = NULL;
  CK_ATTRIBUTE *attrs;
  CK_ATTRIBUTE theTemplate[20];
  CK_BBOOL cktrue = CK_TRUE;
  CK_BBOOL ckfalse = CK_FALSE;
  CK_OBJECT_CLASS objClass = CKO_CERTIFICATE;
  char slotname[SLOTSIZE];
#endif
  CERTCertificate *cert;
  char *nickname = NULL;
  char *n = NULL;

  /* If there is no slash in the filename it is assumed to be a regular
   * NSS nickname.
   */
  if(is_file(filename)) {
    n = strrchr(filename, '/');
    if(n)
      n++;
    if(!mod)
      return 1;
  }
  else {
    /* A nickname from the NSS internal database */
    if(cacert)
      return 0; /* You can't specify an NSS CA nickname this way */
    nickname = strdup(filename);
    if(!nickname)
      return 0;
    goto done;
  }

#ifdef HAVE_PK11_CREATEGENERICOBJECT
  attrs = theTemplate;

  /* All CA and trust objects go into slot 0. Other slots are used
   * for storing certificates. With each new user certificate we increment
   * the slot count. We only support 1 user certificate right now.
   */
  if(cacert)
    slotID = 0;
  else
    slotID = 1;

  snprintf(slotname, SLOTSIZE, "PEM Token #%ld", slotID);

  nickname = aprintf("PEM Token #%ld:%s", slotID, n);
  if(!nickname)
    return 0;

  slot = PK11_FindSlotByName(slotname);

  if(!slot) {
    free(nickname);
    return 0;
  }

  PK11_SETATTRS(attrs, CKA_CLASS, &objClass, sizeof(objClass) );
  attrs++;
  PK11_SETATTRS(attrs, CKA_TOKEN, &cktrue, sizeof(CK_BBOOL) );
  attrs++;
  PK11_SETATTRS(attrs, CKA_LABEL, (unsigned char *)filename,
                strlen(filename)+1);
  attrs++;
  if(cacert) {
    PK11_SETATTRS(attrs, CKA_TRUST, &cktrue, sizeof(CK_BBOOL) );
  }
  else {
    PK11_SETATTRS(attrs, CKA_TRUST, &ckfalse, sizeof(CK_BBOOL) );
  }
  attrs++;

  /* This load the certificate in our PEM module into the appropriate
   * slot.
   */
  ssl->cacert[slotID] = PK11_CreateGenericObject(slot, theTemplate, 4,
                                         PR_FALSE /* isPerm */);

  PK11_FreeSlot(slot);

  if(ssl->cacert[slotID] == NULL) {
    free(nickname);
    return 0;
  }
#else
  /* We don't have PK11_CreateGenericObject but a file-based cert was passed
   * in. We need to fail.
   */
  return 0;
#endif

done:
  /* Double-check that the certificate or nickname requested exists in
   * either the token or the NSS certificate database.
   */
  if(!cacert) {
    cert = PK11_FindCertFromNickname((char *)nickname, NULL);

    /* An invalid nickname was passed in */
    if(cert == NULL) {
      free(nickname);
      PR_SetError(SEC_ERROR_UNKNOWN_CERT, 0);
      return 0;
    }

    CERT_DestroyCertificate(cert);
  }

  free(nickname);

  return 1;
}
コード例 #25
0
ファイル: TLSServer.cpp プロジェクト: leplatrem/gecko-dev
SECStatus
ConfigSecureServerWithNamedCert(PRFileDesc *fd, const char *certName,
                                /*optional*/ ScopedCERTCertificate *certOut,
                                /*optional*/ SSLKEAType *keaOut)
{
  ScopedCERTCertificate cert(PK11_FindCertFromNickname(certName, nullptr));
  if (!cert) {
    PrintPRError("PK11_FindCertFromNickname failed");
    return SECFailure;
  }
  // If an intermediate certificate issued the server certificate (rather than
  // directly by a trust anchor), we want to send it along in the handshake so
  // we don't encounter unknown issuer errors when that's not what we're
  // testing.
  UniqueCERTCertificateList certList;
  ScopedCERTCertificate issuerCert(
    CERT_FindCertByName(CERT_GetDefaultCertDB(), &cert->derIssuer));
  // If we can't find the issuer cert, continue without it.
  if (issuerCert) {
    // Sadly, CERTCertificateList does not have a CERT_NewCertificateList
    // utility function, so we must create it ourselves. This consists
    // of creating an arena, allocating space for the CERTCertificateList,
    // and then transferring ownership of the arena to that list.
    ScopedPLArenaPool arena(PORT_NewArena(DER_DEFAULT_CHUNKSIZE));
    if (!arena) {
      PrintPRError("PORT_NewArena failed");
      return SECFailure;
    }
    certList.reset(static_cast<CERTCertificateList*>(
      PORT_ArenaAlloc(arena.get(), sizeof(CERTCertificateList))));
    if (!certList) {
      PrintPRError("PORT_ArenaAlloc failed");
      return SECFailure;
    }
    certList->arena = arena.forget();
    // We also have to manually copy the certificates we care about to the
    // list, because there aren't any utility functions for that either.
    certList->certs = reinterpret_cast<SECItem*>(
      PORT_ArenaAlloc(certList->arena, 2 * sizeof(SECItem)));
    if (SECITEM_CopyItem(certList->arena, certList->certs, &cert->derCert)
          != SECSuccess) {
      PrintPRError("SECITEM_CopyItem failed");
      return SECFailure;
    }
    if (SECITEM_CopyItem(certList->arena, certList->certs + 1,
                         &issuerCert->derCert) != SECSuccess) {
      PrintPRError("SECITEM_CopyItem failed");
      return SECFailure;
    }
    certList->len = 2;
  }

  ScopedPK11SlotInfo slot(PK11_GetInternalKeySlot());
  UniqueSECKEYPrivateKey key(
    PK11_FindKeyByDERCert(slot.get(), cert.get(), nullptr));
  if (!key) {
    PrintPRError("PK11_FindKeyByDERCert failed");
    return SECFailure;
  }

  SSLKEAType certKEA = NSS_FindCertKEAType(cert);

  if (SSL_ConfigSecureServerWithCertChain(fd, cert.get(), certList.get(),
                                          key.get(), certKEA) != SECSuccess) {
    PrintPRError("SSL_ConfigSecureServer failed");
    return SECFailure;
  }

  if (certOut) {
    *certOut = cert.forget();
  }

  if (keaOut) {
    *keaOut = certKEA;
  }

  return SECSuccess;
}
コード例 #26
0
/*
 * Find a user certificate that matchs the given criteria.
 * 
 *	"handle" - database to search
 *	"nickname" - nickname to match
 *	"usage" - certificate usage to match
 *	"validOnly" - only return certs that are curently valid
 *	"proto_win" - window handle passed to pkcs11
 */
CERTCertificate *
CERT_FindUserCertByUsage(CERTCertDBHandle *handle,
			 const char *nickname,
			 SECCertUsage usage,
			 PRBool validOnly,
			 void *proto_win)
{
    CERTCertificate *cert = NULL;
    CERTCertList *certList = NULL;
    SECStatus rv;
    int64 time;
    
    time = PR_Now();
    
    /* use the pk11 call so that we pick up any certs on tokens,
     * which may require login
     */
    /* XXX - why is this restricted? */
    if ( proto_win != NULL ) {
	cert = PK11_FindCertFromNickname(nickname,proto_win);
    }


    /* sigh, There are still problems find smart cards from the temp
     * db. This will get smart cards working again. The real fix
     * is to make sure we can search the temp db by their token nickname.
     */
    if (cert == NULL) {
	cert = CERT_FindCertByNickname(handle,nickname);
    }

    if ( cert != NULL ) {
	unsigned int requiredKeyUsage;
	unsigned int requiredCertType;

	rv = CERT_KeyUsageAndTypeForCertUsage(usage, PR_FALSE,
					&requiredKeyUsage, &requiredCertType);
	if ( rv != SECSuccess ) {
	    /* drop the extra reference */
	    CERT_DestroyCertificate(cert);
	    cert = NULL;
	    goto loser;
	}
	/* If we already found the right cert, just return it */
	if ( (!validOnly || CERT_CheckCertValidTimes(cert, time, PR_FALSE)
	      == secCertTimeValid) &&
	     (CERT_CheckKeyUsage(cert, requiredKeyUsage) == SECSuccess) &&
	     (cert->nsCertType & requiredCertType) &&
	      CERT_IsUserCert(cert) ) {
	    return(cert);
	}

 	/* collect certs for this nickname, sorting them into the list */
	certList = CERT_CreateSubjectCertList(certList, handle, 
					&cert->derSubject, time, validOnly);

	CERT_FilterCertListForUserCerts(certList);

	/* drop the extra reference */
	CERT_DestroyCertificate(cert);
	cert = NULL;
    }
	
    if ( certList == NULL ) {
	goto loser;
    }
    
    /* remove certs with incorrect usage */
    rv = CERT_FilterCertListByUsage(certList, usage, PR_FALSE);

    if ( rv != SECSuccess ) {
	goto loser;
    }

    if ( ! CERT_LIST_END(CERT_LIST_HEAD(certList), certList) ) {
	cert = CERT_DupCertificate(CERT_LIST_HEAD(certList)->cert);
    }
    
loser:
    if ( certList != NULL ) {
	CERT_DestroyCertList(certList);
    }

    return(cert);
}
コード例 #27
0
/*
 * Find all user certificates that match the given criteria.
 * 
 *	"handle" - database to search
 *	"usage" - certificate usage to match
 *	"oneCertPerName" - if set then only return the "best" cert per
 *			name
 *	"validOnly" - only return certs that are curently valid
 *	"proto_win" - window handle passed to pkcs11
 */
CERTCertList *
CERT_FindUserCertsByUsage(CERTCertDBHandle *handle,
			  SECCertUsage usage,
			  PRBool oneCertPerName,
			  PRBool validOnly,
			  void *proto_win)
{
    CERTCertNicknames *nicknames = NULL;
    char **nnptr;
    int nn;
    CERTCertificate *cert = NULL;
    CERTCertList *certList = NULL;
    SECStatus rv;
    int64 time;
    CERTCertListNode *node = NULL;
    CERTCertListNode *freenode = NULL;
    int n;
    
    time = PR_Now();
    
    nicknames = CERT_GetCertNicknames(handle, SEC_CERT_NICKNAMES_USER,
				      proto_win);
    
    if ( ( nicknames == NULL ) || ( nicknames->numnicknames == 0 ) ) {
	goto loser;
    }

    nnptr = nicknames->nicknames;
    nn = nicknames->numnicknames;

    while ( nn > 0 ) {
	cert = NULL;
	/* use the pk11 call so that we pick up any certs on tokens,
	 * which may require login
	 */
	if ( proto_win != NULL ) {
	    cert = PK11_FindCertFromNickname(*nnptr,proto_win);
	}

	/* Sigh, It turns out if the cert is already in the temp db, because
	 * it's in the perm db, then the nickname lookup doesn't work.
	 * since we already have the cert here, though, than we can just call
	 * CERT_CreateSubjectCertList directly. For those cases where we didn't
	 * find the cert in pkcs #11 (because we didn't have a password arg,
	 * or because the nickname is for a peer, server, or CA cert, then we
	 * go look the cert up.
	 */
	if (cert == NULL) { 
	    cert = CERT_FindCertByNickname(handle,*nnptr);
	}

	if ( cert != NULL ) {
	   /* collect certs for this nickname, sorting them into the list */
	    certList = CERT_CreateSubjectCertList(certList, handle, 
				&cert->derSubject, time, validOnly);

	    CERT_FilterCertListForUserCerts(certList);
	
	    /* drop the extra reference */
	    CERT_DestroyCertificate(cert);
	}
	
	nnptr++;
	nn--;
    }

    /* remove certs with incorrect usage */
    rv = CERT_FilterCertListByUsage(certList, usage, PR_FALSE);

    if ( rv != SECSuccess ) {
	goto loser;
    }

    /* remove any extra certs for each name */
    if ( oneCertPerName ) {
	PRBool *flags;

	nn = nicknames->numnicknames;
	nnptr = nicknames->nicknames;
	
	flags = (PRBool *)PORT_ZAlloc(sizeof(PRBool) * nn);
	if ( flags == NULL ) {
	    goto loser;
	}
	
	node = CERT_LIST_HEAD(certList);
	
	/* treverse all certs in the list */
	while ( !CERT_LIST_END(node, certList) ) {

	    /* find matching nickname index */
	    for ( n = 0; n < nn; n++ ) {
		if ( CERT_MatchNickname(nnptr[n], node->cert->nickname) ) {
		    /* We found a match.  If this is the first one, then
		     * set the flag and move on to the next cert.  If this
		     * is not the first one then delete it from the list.
		     */
		    if ( flags[n] ) {
			/* We have already seen a cert with this nickname,
			 * so delete this one.
			 */
			freenode = node;
			node = CERT_LIST_NEXT(node);
			CERT_RemoveCertListNode(freenode);
		    } else {
			/* keep the first cert for each nickname, but set the
			 * flag so we know to delete any others with the same
			 * nickname.
			 */
			flags[n] = PR_TRUE;
			node = CERT_LIST_NEXT(node);
		    }
		    break;
		}
	    }
	    if ( n == nn ) {
		/* if we get here it means that we didn't find a matching
		 * nickname, which should not happen.
		 */
		PORT_Assert(0);
		node = CERT_LIST_NEXT(node);
	    }
	}
	PORT_Free(flags);
    }

    goto done;
    
loser:
    if ( certList != NULL ) {
	CERT_DestroyCertList(certList);
	certList = NULL;
    }

done:
    if ( nicknames != NULL ) {
	CERT_FreeNicknames(nicknames);
    }

    return(certList);
}
コード例 #28
0
ファイル: nss.c プロジェクト: 0w/moai-dev
/**
 *
 * Callback to pick the SSL client certificate.
 */
static SECStatus SelectClientCert(void *arg, PRFileDesc *sock,
                                  struct CERTDistNamesStr *caNames,
                                  struct CERTCertificateStr **pRetCert,
                                  struct SECKEYPrivateKeyStr **pRetKey)
{
  static const char pem_nickname[] = "PEM Token #1";
  const char *pem_slotname = pem_nickname;

  struct ssl_connect_data *connssl = (struct ssl_connect_data *)arg;
  struct SessionHandle *data = connssl->data;
  const char *nickname = connssl->client_nickname;

  if (mod && nickname &&
      0 == strncmp(nickname, pem_nickname, /* length of "PEM Token" */ 9)) {

    /* use the cert/key provided by PEM reader */
    PK11SlotInfo *slot;
    void *proto_win = SSL_RevealPinArg(sock);
    *pRetKey = NULL;

    *pRetCert = PK11_FindCertFromNickname(nickname, proto_win);
    if (NULL == *pRetCert) {
      failf(data, "NSS: client certificate not found: %s", nickname);
      return SECFailure;
    }

    slot = PK11_FindSlotByName(pem_slotname);
    if (NULL == slot) {
      failf(data, "NSS: PK11 slot not found: %s", pem_slotname);
      return SECFailure;
    }

    *pRetKey = PK11_FindPrivateKeyFromCert(slot, *pRetCert, NULL);
    PK11_FreeSlot(slot);
    if (NULL == *pRetKey) {
      failf(data, "NSS: private key not found for certificate: %s", nickname);
      return SECFailure;
    }

    infof(data, "NSS: client certificate: %s\n", nickname);
    display_cert_info(data, *pRetCert);
    return SECSuccess;
  }

  /* use the default NSS hook */
  if (SECSuccess != NSS_GetClientAuthData((void *)nickname, sock, caNames,
                                          pRetCert, pRetKey)
      || NULL == *pRetCert) {

    if (NULL == nickname)
      failf(data, "NSS: client certificate not found (nickname not specified)");
    else
      failf(data, "NSS: client certificate not found: %s", nickname);

    return SECFailure;
  }

  /* get certificate nickname if any */
  nickname = (*pRetCert)->nickname;
  if (NULL == nickname)
    nickname = "[unknown]";

  if (NULL == *pRetKey) {
    failf(data, "NSS: private key not found for certificate: %s", nickname);
    return SECFailure;
  }

  infof(data, "NSS: using client certificate: %s\n", nickname);
  display_cert_info(data, *pRetCert);
  return SECSuccess;
}
コード例 #29
0
ファイル: secureserver.c プロジェクト: goodwinos/pcp
int
__pmSecureServerInit(void)
{
    const PRUint16 *cipher;
    SECStatus secsts;
    int pathSpecified;
    int sts = 0;

    PM_INIT_LOCKS();
    PM_LOCK(secureserver_lock);

    /* Only attempt this once. */
    if (secure_server.initialized)
	goto done;
    secure_server.initialized = 1;

    if (PR_Initialized() != PR_TRUE)
	PR_Init(PR_SYSTEM_THREAD, PR_PRIORITY_NORMAL, 1);

    /* Configure optional (cmdline) password file in case DB locked */
    PK11_SetPasswordFunc(certificate_database_password);

    /*
     * Configure location of the NSS database with a sane default.
     * For servers, we default to the shared (sql) system-wide database.
     * If command line db specified, pass it directly through - allowing
     * any old database format, at the users discretion.
     */
    if (!secure_server.database_path[0]) {
	const char *path;
	pathSpecified = 0;
	path = serverdb(secure_server.database_path, MAXPATHLEN, "sql:");

	/* this is the default case on some platforms, so no log spam */
	if (access(path, R_OK|X_OK) < 0) {
	    if (pmDebugOptions.context)
		pmNotifyErr(LOG_INFO,
			      "Cannot access system security database: %s",
			      secure_server.database_path);
	    sts = -EOPNOTSUPP;	/* not fatal - just no secure connections */
	    secure_server.init_failed = 1;
	    goto done;
	}
    }
    else
	pathSpecified = 1;

    /*
     * pmproxy acts as both a client and server. Since the
     * server init path happens first, the db previously
     * got opened readonly.  Instead try to open RW.
     * Fallback if there is an error.
     */

    secsts = NSS_InitReadWrite(secure_server.database_path);

    if( secsts != SECSuccess )
    	secsts = NSS_Init(secure_server.database_path);

    if (secsts != SECSuccess && !pathSpecified) {
	/* fallback, older versions of NSS do not support sql: */
	serverdb(secure_server.database_path, MAXPATHLEN, "");
	secsts = NSS_Init(secure_server.database_path);
    }

    if (secsts != SECSuccess) {
	pmNotifyErr(LOG_ERR, "Cannot setup certificate DB (%s): %s",
			secure_server.database_path,
			pmErrStr(__pmSecureSocketsError(PR_GetError())));
	sts = -EOPNOTSUPP;	/* not fatal - just no secure connections */
	secure_server.init_failed = 1;
	goto done;
    }

    /* Some NSS versions don't do this correctly in NSS_SetDomesticPolicy. */
    for (cipher = SSL_GetImplementedCiphers(); *cipher != 0; ++cipher)
	SSL_CipherPolicySet(*cipher, SSL_ALLOWED);

    /* Configure SSL session cache for multi-process server, using defaults */
    secsts = SSL_ConfigMPServerSIDCache(1, 0, 0, NULL);
    if (secsts != SECSuccess) {
	pmNotifyErr(LOG_ERR, "Unable to configure SSL session ID cache: %s",
		pmErrStr(__pmSecureSocketsError(PR_GetError())));
	sts = -EOPNOTSUPP;	/* not fatal - just no secure connections */
	secure_server.init_failed = 1;
	goto done;
    } else {
	secure_server.ssl_session_cache_setup = 1;
    }

    /*
     * Iterate over any/all PCP Collector nickname certificates,
     * seeking one valid certificate.  No-such-nickname is not an
     * error (not configured by admin at all) but anything else is.
     */
    CERTCertList *certlist;
    CERTCertDBHandle *nssdb = CERT_GetDefaultCertDB();
    CERTCertificate *dbcert = PK11_FindCertFromNickname(secure_server.cert_nickname, NULL);

    if (dbcert) {
	PRTime now = PR_Now();
	SECItem *name = &dbcert->derSubject;
	CERTCertListNode *node;

	certlist = CERT_CreateSubjectCertList(NULL, nssdb, name, now, PR_FALSE);
	if (certlist) {
	    for (node = CERT_LIST_HEAD(certlist);
		 !CERT_LIST_END(node, certlist);
		 node = CERT_LIST_NEXT (node)) {
		if (pmDebugOptions.context)
		    __pmDumpCertificate(stderr, secure_server.cert_nickname, node->cert);
		if (!__pmValidCertificate(nssdb, node->cert, now))
		    continue;
		secure_server.certificate_verified = 1;
		break;
	    }
	    CERT_DestroyCertList(certlist);
	}

	if (secure_server.certificate_verified) {
	    secure_server.certificate_KEA = NSS_FindCertKEAType(dbcert);
	    secure_server.private_key = PK11_FindKeyByAnyCert(dbcert, NULL);
	    if (!secure_server.private_key) {
		pmNotifyErr(LOG_ERR, "Unable to extract %s private key",
				secure_server.cert_nickname);
		CERT_DestroyCertificate(dbcert);
		secure_server.certificate_verified = 0;
		sts = -EOPNOTSUPP;	/* not fatal - just no secure connections */
		secure_server.init_failed = 1;
		goto done;
	    }
	} else {
	    pmNotifyErr(LOG_ERR, "Unable to find a valid %s", secure_server.cert_nickname);
	    CERT_DestroyCertificate(dbcert);
	    sts = -EOPNOTSUPP;	/* not fatal - just no secure connections */
	    secure_server.init_failed = 1;
	    goto done;
	}
    }

    if (! secure_server.certificate_verified) {
	if (pmDebugOptions.context) {
	    pmNotifyErr(LOG_INFO, "No valid %s in security database: %s",
			  secure_server.cert_nickname, secure_server.database_path);
	}
	sts = -EOPNOTSUPP;	/* not fatal - just no secure connections */
	secure_server.init_failed = 1;
	goto done;
    }

    secure_server.certificate = dbcert;
    secure_server.init_failed = 0;
    sts = 0;

done:
    PM_UNLOCK(secureserver_lock);
    return sts;
}
コード例 #30
0
ファイル: vcard_emul_nss.c プロジェクト: AVEx-6502/qemu-6502
VCardEmulError
vcard_emul_init(const VCardEmulOptions *options)
{
    SECStatus rv;
    PRBool ret, has_readers = PR_FALSE, need_coolkey_module;
    VReader *vreader;
    VReaderEmul *vreader_emul;
    SECMODListLock *module_lock;
    SECMODModuleList *module_list;
    SECMODModuleList *mlp;
    int i;

    if (vcard_emul_init_called) {
        return VCARD_EMUL_INIT_ALREADY_INITED;
    }
    vcard_emul_init_called = 1;
    vreader_init();
    vevent_queue_init();

    if (options == NULL) {
        options = &default_options;
    }

    /* first initialize NSS */
    if (options->nss_db) {
        rv = NSS_Init(options->nss_db);
    } else {
        rv = NSS_Init("sql:/etc/pki/nssdb");
    }
    if (rv != SECSuccess) {
        return VCARD_EMUL_FAIL;
    }
    /* Set password callback function */
    PK11_SetPasswordFunc(vcard_emul_get_password);

    /* set up soft cards emulated by software certs rather than physical cards
     * */
    for (i = 0; i < options->vreader_count; i++) {
        int j;
        int cert_count;
        unsigned char **certs;
        int *cert_len;
        VCardKey **keys;
        PK11SlotInfo *slot;

        slot = PK11_FindSlotByName(options->vreader[i].name);
        if (slot == NULL) {
            continue;
        }
        vreader_emul = vreader_emul_new(slot, options->vreader[i].card_type,
                                        options->vreader[i].type_params);
        vreader = vreader_new(options->vreader[i].vname, vreader_emul,
                              vreader_emul_delete);
        vreader_add_reader(vreader);
        cert_count = options->vreader[i].cert_count;

        ret = vcard_emul_alloc_arrays(&certs, &cert_len, &keys,
                                      options->vreader[i].cert_count);
        if (ret == PR_FALSE) {
            continue;
        }
        cert_count = 0;
        for (j = 0; j < options->vreader[i].cert_count; j++) {
            /* we should have a better way of identifying certs than by
             * nickname here */
            CERTCertificate *cert = PK11_FindCertFromNickname(
                                        options->vreader[i].cert_name[j],
                                        NULL);
            if (cert == NULL) {
                continue;
            }
            certs[cert_count] = cert->derCert.data;
            cert_len[cert_count] = cert->derCert.len;
            keys[cert_count] = vcard_emul_make_key(slot, cert);
            /* this is safe because the key is still holding a cert reference */
            CERT_DestroyCertificate(cert);
            cert_count++;
        }
        if (cert_count) {
            VCard *vcard = vcard_emul_make_card(vreader, certs, cert_len,
                                                keys, cert_count);
            vreader_insert_card(vreader, vcard);
            vcard_emul_init_series(vreader, vcard);
            /* allow insertion and removal of soft cards */
            vreader_emul->saved_vcard = vcard_reference(vcard);
            vcard_free(vcard);
            vreader_free(vreader);
            has_readers = PR_TRUE;
        }
        g_free(certs);
        g_free(cert_len);
        g_free(keys);
    }

    /* if we aren't suppose to use hw, skip looking up hardware tokens */
    if (!options->use_hw) {
        nss_emul_init = has_readers;
        return has_readers ? VCARD_EMUL_OK : VCARD_EMUL_FAIL;
    }

    /* make sure we have some PKCS #11 module loaded */
    module_lock = SECMOD_GetDefaultModuleListLock();
    module_list = SECMOD_GetDefaultModuleList();
    need_coolkey_module = !has_readers;
    SECMOD_GetReadLock(module_lock);
    for (mlp = module_list; mlp; mlp = mlp->next) {
        SECMODModule *module = mlp->module;
        if (module_has_removable_hw_slots(module)) {
            need_coolkey_module = PR_FALSE;
            break;
        }
    }
    SECMOD_ReleaseReadLock(module_lock);

    if (need_coolkey_module) {
        SECMODModule *module;
        module = SECMOD_LoadUserModule(
                    (char *)"library=libcoolkeypk11.so name=Coolkey",
                    NULL, PR_FALSE);
        if (module == NULL) {
            return VCARD_EMUL_FAIL;
        }
        SECMOD_DestroyModule(module); /* free our reference, Module will still
                                       * be on the list.
                                       * until we destroy it */
    }

    /* now examine all the slots, finding which should be readers */
    /* We should control this with options. For now we mirror out any
     * removable hardware slot */
    default_card_type = options->hw_card_type;
    default_type_params = strdup(options->hw_type_params);

    SECMOD_GetReadLock(module_lock);
    for (mlp = module_list; mlp; mlp = mlp->next) {
        SECMODModule *module = mlp->module;
        PRBool has_emul_slots = PR_FALSE;

        if (module == NULL) {
                continue;
        }

        for (i = 0; i < module->slotCount; i++) {
            PK11SlotInfo *slot = module->slots[i];

            /* only map removable HW slots */
            if (slot == NULL || !PK11_IsRemovable(slot) || !PK11_IsHW(slot)) {
                continue;
            }
            vreader_emul = vreader_emul_new(slot, options->hw_card_type,
                                            options->hw_type_params);
            vreader = vreader_new(PK11_GetSlotName(slot), vreader_emul,
                                  vreader_emul_delete);
            vreader_add_reader(vreader);

            has_readers = PR_TRUE;
            has_emul_slots = PR_TRUE;

            if (PK11_IsPresent(slot)) {
                VCard *vcard;
                vcard = vcard_emul_mirror_card(vreader);
                vreader_insert_card(vreader, vcard);
                vcard_emul_init_series(vreader, vcard);
                vcard_free(vcard);
            }
        }
        if (has_emul_slots) {
            vcard_emul_new_event_thread(module);
        }
    }
    SECMOD_ReleaseReadLock(module_lock);
    nss_emul_init = has_readers;

    return VCARD_EMUL_OK;
}