예제 #1
0
/**
 * 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;
}
예제 #2
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;
}
예제 #3
0
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);
}
예제 #4
0
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);
}
예제 #5
0
/*
 *  j a r _ f i n d _ k e y _ t y p e
 * 
 *  Determine the key type for a given cert, which 
 * should be rsaKey or dsaKey. Any error return 0.
 *
 */
static int	
jar_find_key_type (CERTCertificate *cert)
{
    SECKEYPrivateKey * privk = NULL;
    KeyType keyType;

    /* determine its type */
    privk = PK11_FindKeyByAnyCert (cert, &pwdata);
    if (privk == NULL) {
	PR_fprintf(errorFD, "warning - can't find private key for this cert\n");
	warningCount++;
	return 0;
    }

    keyType = privk->keyType;
    SECKEY_DestroyPrivateKey (privk);
    return keyType;
}
예제 #6
0
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);
}
예제 #7
0
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;
}
예제 #8
0
파일: FileSSL.c 프로젝트: stoneskill/mix-n2
int FileSSL_main(int argc, char * argv[])
{
    bool isServer = true;
    
    SECStatus rv = SECSuccess;

    
    char buffer[32] = {0};
    

    PR_Init(PR_SYSTEM_THREAD, PR_PRIORITY_NORMAL, 1);
    
    PK11_SetPasswordFunc(GetModulePassword);
    rv = NSS_Initialize(GetSystemDBDir(),
                        "", "",
                        "secmod.db", 0);
    
    
    rv = SSL_OptionSetDefault(SSL_SECURITY, PR_TRUE);
    rv = SSL_OptionSetDefault(SSL_SOCKS, PR_TRUE);
    rv = SSL_OptionSetDefault(SSL_ENABLE_SSL2, PR_TRUE);
    rv = SSL_OptionSetDefault(SSL_ENABLE_SSL3, PR_TRUE);
    rv = SSL_OptionSetDefault(SSL_ENABLE_FDX, PR_TRUE);
    
    rv = SSL_OptionSetDefault(SSL_ENABLE_TLS, PR_TRUE);
    
    rv = NSS_SetDomesticPolicy();
    rv = NSS_SetExportPolicy();
    rv = NSS_SetFrancePolicy();
    //    rv = SSL_CipherPolicySet();
    
    
    
    SSL_ClearSessionCache();
    
    rv = SSL_ConfigServerSessionIDCache(10, 30 , 30, ".");
    
    
    PRFileDesc * socket = PR_NewTCPSocket();
    
    socket = SSL_ImportFD(NULL,socket);
    
    
    
    if (isServer) {
        
        CERTCertDBHandle *certHandle;
        
        certHandle = CERT_GetDefaultCertDB();
        
        char * nickname = "itrus Certificate DB:2013-11-15 12:44:10";/*nickname*/
        
        CERTCertificate* cert = NULL;
        cert = CERT_FindCertByNicknameOrEmailAddr(certHandle, nickname);
        
        
        SECKEYPrivateKey *prvKey = NULL;
        
        prvKey = PK11_FindKeyByAnyCert(cert, NULL);
        
        rv = SSL_ConfigSecureServer(socket, cert,prvKey,ssl_kea_rsa);
        
        
        PRNetAddr netAddr;
        
        PRNetAddr netAddrLocal;
        
        
        rv = PR_InitializeNetAddr(0, 8888, &netAddr);
        
        
        rv = PR_StringToNetAddr("127.0.0.1", &netAddrLocal);
        
        rv = PR_Bind(socket,&netAddr);
        rv = PR_Listen(socket, 100);
        
        
        while (1) {
            PRFileDesc * client = PR_Accept(socket, &netAddr, 6000000);
            PRNetAddr addr;
            
            
            rv = PR_GetSockName(client, &addr);
            
            rv = SSL_ForceHandshake(client);
            
            
            rv = PR_Write(client,"123", 4);
            
            sleep(1);
        }
        
    }
    else
    {
        rv = SSL_SetURL(socket, "127.0.0.1");
        
        PRNetAddr netAddr;
        
        PRNetAddr netAddrLocal;
        
        
        rv = PR_InitializeNetAddr(0, 8888, &netAddr);
        
        
        rv = PR_StringToNetAddr("127.0.0.1", &netAddrLocal);
        
        //        rv = PR_GetHostByName();
        //        PR_EnumerateHostEnt
        rv = PR_Connect(socket,&netAddr, 300000);
        
        rv = SSL_AuthCertificateHook(socket, OwnAuthCertHandler, NULL);
        
        rv = SSL_ForceHandshake(socket);
        
        while (1) {
            rv = PR_Read(socket,buffer, 32);
            
            sleep(1);
        }
        
    }
    
    
    return 0;
}
예제 #9
0
static xmlSecKeyPtr 
xmlSecNssKeysStoreFindKey(xmlSecKeyStorePtr store, const xmlChar* name, 
		          xmlSecKeyInfoCtxPtr keyInfoCtx) {
    xmlSecKeyStorePtr* ss;
    xmlSecKeyPtr key = NULL;
    xmlSecKeyPtr retval = NULL;
    xmlSecKeyReqPtr keyReq = NULL;
    CERTCertificate *cert = NULL;
    SECKEYPublicKey *pubkey = NULL;
    SECKEYPrivateKey *privkey = NULL;
    xmlSecKeyDataPtr data = NULL;
    xmlSecKeyDataPtr x509Data = NULL;
    int ret;

    xmlSecAssert2(xmlSecKeyStoreCheckId(store, xmlSecNssKeysStoreId), NULL);
    xmlSecAssert2(keyInfoCtx != NULL, NULL);

    ss = xmlSecNssKeysStoreGetSS(store);
    xmlSecAssert2(((ss != NULL) && (*ss != NULL)), NULL);

    key = xmlSecKeyStoreFindKey(*ss, name, keyInfoCtx);
    if (key != NULL) {
	return (key);
    }

    /* Try to find the key in the NSS DB, and construct an xmlSecKey.
     * we must have a name to lookup keys in NSS DB.
     */
    if (name == NULL) {
	goto done;
    }

    /* what type of key are we looking for? 
     * TBD: For now, we'll look only for public/private keys using the
     * name as a cert nickname. Later on, we can attempt to find
     * symmetric keys using PK11_FindFixedKey 
     */
    keyReq = &(keyInfoCtx->keyReq);
    if (keyReq->keyType & 
	(xmlSecKeyDataTypePublic | xmlSecKeyDataTypePrivate)) {
	cert = CERT_FindCertByNickname (CERT_GetDefaultCertDB(), (char *)name);
	if (cert == NULL) {
	    goto done;
	}

	if (keyReq->keyType & xmlSecKeyDataTypePublic) {
 	    pubkey = CERT_ExtractPublicKey(cert);
	    if (pubkey == NULL) {
		xmlSecErr_a_ignorar5(XMLSEC_ERRORS_HERE,
			    NULL,
			    "CERT_ExtractPublicKey",
			    XMLSEC_ERRORS_R_CRYPTO_FAILED,
			    XMLSEC_ERRORS_NO_MESSAGE);
		goto done;
	    }
	} 

	if (keyReq->keyType & xmlSecKeyDataTypePrivate) { 
 	    privkey = PK11_FindKeyByAnyCert(cert, NULL);
	    if (privkey == NULL) {
		xmlSecErr_a_ignorar5(XMLSEC_ERRORS_HERE,
			    NULL,
			    "PK11_FindKeyByAnyCert",
			    XMLSEC_ERRORS_R_CRYPTO_FAILED,
			    XMLSEC_ERRORS_NO_MESSAGE);
		goto done;
	    }
	}

	data = xmlSecNssPKIAdoptKey(privkey, pubkey);
	if(data == NULL) {
	    xmlSecErr_a_ignorar5(XMLSEC_ERRORS_HERE,
			NULL,
			"xmlSecNssPKIAdoptKey",
			XMLSEC_ERRORS_R_XMLSEC_FAILED,
			XMLSEC_ERRORS_NO_MESSAGE);
	    goto done;
	}    
	privkey = NULL;
	pubkey = NULL;

        key = xmlSecKeyCreate();
        if (key == NULL) {
	    xmlSecErr_a_ignorar5(XMLSEC_ERRORS_HERE,
			NULL,
			"xmlSecKeyCreate",
			XMLSEC_ERRORS_R_XMLSEC_FAILED,
			XMLSEC_ERRORS_NO_MESSAGE);
	    return (NULL);
        }

	x509Data = xmlSecKeyDataCreate(xmlSecNssKeyDataX509Id);
	if(x509Data == NULL) {
	    xmlSecErr_a_ignorar6(XMLSEC_ERRORS_HERE,
			NULL,
			"xmlSecKeyDataCreate",
			XMLSEC_ERRORS_R_XMLSEC_FAILED,
			"transform=%s",
			xmlSecErrorsSafeString(xmlSecTransformKlassGetName(xmlSecNssKeyDataX509Id)));
	    goto done;
	}

	ret = xmlSecNssKeyDataX509AdoptKeyCert(x509Data, cert);
	if (ret < 0) {
	    xmlSecErr_a_ignorar6(XMLSEC_ERRORS_HERE,
			NULL,
			"xmlSecNssKeyDataX509AdoptKeyCert",
			XMLSEC_ERRORS_R_XMLSEC_FAILED,
			"data=%s",
			xmlSecErrorsSafeString(xmlSecKeyDataGetName(x509Data)));
	    goto done;
	}
	cert = CERT_DupCertificate(cert);
	if (cert == NULL) {
	    xmlSecErr_a_ignorar6(XMLSEC_ERRORS_HERE,
			NULL,
			"CERT_DupCertificate",
			XMLSEC_ERRORS_R_CRYPTO_FAILED,
			"data=%s",
			xmlSecErrorsSafeString(xmlSecKeyDataGetName(x509Data)));
	    goto done;
	}

	ret = xmlSecNssKeyDataX509AdoptCert(x509Data, cert);
	if (ret < 0) {
	    xmlSecErr_a_ignorar6(XMLSEC_ERRORS_HERE,
			NULL,
			"xmlSecNssKeyDataX509AdoptCert",
			XMLSEC_ERRORS_R_XMLSEC_FAILED,
			"data=%s",
			xmlSecErrorsSafeString(xmlSecKeyDataGetName(x509Data)));
	    goto done;
	}
	cert = NULL;

	ret = xmlSecKeySetValue(key, data);
	if (ret < 0) {
	    xmlSecErr_a_ignorar6(XMLSEC_ERRORS_HERE,
			NULL,
			"xmlSecKeySetValue",
			XMLSEC_ERRORS_R_XMLSEC_FAILED,
			"data=%s", 
			xmlSecErrorsSafeString(xmlSecKeyDataGetName(data)));
	    goto done;
	}
	data = NULL;

	ret = xmlSecKeyAdoptData(key, x509Data);
	if (ret < 0) {
	    xmlSecErr_a_ignorar6(XMLSEC_ERRORS_HERE,
			NULL,
			"xmlSecKeyAdoptData",
			XMLSEC_ERRORS_R_XMLSEC_FAILED,
			"data=%s",
			xmlSecErrorsSafeString(xmlSecKeyDataGetName(x509Data)));
	    goto done;
	}
	x509Data = NULL;

	retval = key;
	key = NULL;
    }

done:
    if (cert != NULL) {
	CERT_DestroyCertificate(cert);
    }
    if (pubkey != NULL) {
	SECKEY_DestroyPublicKey(pubkey);
    }
    if (privkey != NULL) {
	SECKEY_DestroyPrivateKey(privkey);
    }
    if (data != NULL) {
	xmlSecKeyDataDestroy(data);
    }
    if (x509Data != NULL) {
	xmlSecKeyDataDestroy(x509Data);
    }
    if (key != NULL) {
	xmlSecKeyDestroy(key);
    }

    return (retval);
}
예제 #10
0
static int
SignFile(FILE *outFile, PRFileDesc *inFile, CERTCertificate *cert)
{
    SECItem data2sign;
    SECStatus rv;
    char *data;
    SECKEYPrivateKey *privKey;
    SECOidTag algID;
    PLArenaPool *arena;
    CERTSignedData sd;
    SECItem *result;

    if (outFile == NULL || inFile == NULL || cert == NULL)
        return -1;

    /* suck the file in */
    if (SECU_ReadDERFromFile(&data2sign, inFile, PR_FALSE,
                             PR_FALSE) != SECSuccess)
        return -1;

    privKey = NULL;    
    privKey = PK11_FindKeyByAnyCert(cert, NULL);

    algID = SEC_GetSignatureAlgorithmOidTag(privKey->keyType, SEC_OID_SHA1);
    if (algID == SEC_OID_UNKNOWN)
        return -1;
    
    arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
    
    PORT_Memset(&sd, 0, sizeof(CERTSignedData));
    
    rv = SEC_SignData(&(sd.signature), data2sign.data, data2sign.len, privKey, algID);
    if (rv != SECSuccess) {
        fprintf (stderr, "Could not sign.\n");
        return -1;
    }
    sd.signature.len = sd.signature.len << 3;
    
    rv = SECOID_SetAlgorithmID(arena, &sd.signatureAlgorithm, algID, 0);
    if (rv != SECSuccess) {
        fprintf (stderr, "Could not set alg id.\n");
        return -1;
    }

    result = SEC_ASN1EncodeItem(arena, NULL, &sd, CERTSignatureDataTemplate);
    SECITEM_FreeItem(&(sd.signature), PR_FALSE);
    
    if (!result) {
        fprintf (stderr, "Could not encode.\n");
        return -1;
    }

    data = PL_Base64Encode((const char*)result->data, result->len, NULL);
    if (!data)
        return -1;
    
    fputs("signature:\n", outFile);
    fputs(data, outFile);
    fputs("\n", outFile);
    ExportPublicKey(outFile, cert);
    
    SECKEY_DestroyPrivateKey(privKey);
    PORT_FreeArena(arena, PR_FALSE);
    
    return 0;
}
예제 #11
0
int sign_hash(const struct RSA_private_key *k
              , const u_char *hash_val, size_t hash_len
              , u_char *sig_val, size_t sig_len)
{
    SECKEYPrivateKey *privateKey = NULL;
    SECItem signature;
    SECItem data;
    SECItem ckaId;
    PK11SlotInfo *slot = NULL;

    DBG(DBG_CRYPT, DBG_log("RSA_sign_hash: Started using NSS"));

    ckaId.type=siBuffer;
    ckaId.len = k->ckaid_len;
    ckaId.data = DISCARD_CONST(unsigned char *, k->ckaid);

    slot = PK11_GetInternalKeySlot();
    if (slot == NULL) {
	loglog(RC_LOG_SERIOUS, "RSA_sign_hash: Unable to find (slot security) device (err %d)\n", PR_GetError());
	return 0;
    }

    if( PK11_Authenticate(slot, PR_FALSE,osw_return_nss_password_file_info()) == SECSuccess ) {
	DBG(DBG_CRYPT, DBG_log("NSS: Authentication to NSS successful\n"));
    }
    else {
	DBG(DBG_CRYPT, DBG_log("NSS: Authentication to NSS either failed or not required,if NSS DB without password\n"));
    }

    privateKey = PK11_FindKeyByKeyID(slot, &ckaId, osw_return_nss_password_file_info());
    if(privateKey==NULL) {
        DBG(DBG_CRYPT,
            DBG_log("Can't find the private key from the NSS CKA_ID"));
	if(k->pub.nssCert != NULL) {
	   privateKey = PK11_FindKeyByAnyCert(k->pub.nssCert,  osw_return_nss_password_file_info());
           if (privateKey == NULL) {
               loglog(RC_LOG_SERIOUS,
                      "Can't find the private key from the NSS CERT (err %d)",
                      PR_GetError());
           }
	}
    }

    PK11_FreeSlot(slot);

    if (privateKey == NULL) {
	loglog(RC_LOG_SERIOUS, "Can't find the private key from the NSS CERT (err %d)\n", PR_GetError());
	return 0;
    }

    data.type=siBuffer;
    data.len=hash_len;
    data.data = DISCARD_CONST(u_char *, hash_val);

    /*signature.len=PK11_SignatureLen(privateKey);*/
    signature.len=sig_len;
    signature.data=sig_val;

    {
        SECStatus s = PK11_Sign(privateKey, &signature, &data);

        if (s != SECSuccess) {
            loglog(RC_LOG_SERIOUS,
                   "RSA_sign_hash: sign function failed (%d)",
                   PR_GetError());
            return 0;
        }
    }

    DBG(DBG_CRYPT, DBG_log("RSA_sign_hash: Ended using NSS"));
    return signature.len;
}
예제 #12
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;
            }
        }            
    }        
}
예제 #13
0
SECStatus
NSS_CMSUtil_EncryptSymKey_ESDH(PLArenaPool *poolp, CERTCertificate *cert, PK11SymKey *key,
			SECItem *encKey, SECItem **ukm, SECAlgorithmID *keyEncAlg,
			SECItem *pubKey)
{
#if 0 /* not yet done */
    SECOidTag certalgtag;	/* the certificate's encryption algorithm */
    SECOidTag encalgtag;	/* the algorithm used for key exchange/agreement */
    SECStatus rv;
    SECItem *params = NULL;
    int data_len;
    SECStatus err;
    PK11SymKey *tek;
    CERTCertificate *ourCert;
    SECKEYPublicKey *ourPubKey;
    NSSCMSKEATemplateSelector whichKEA = NSSCMSKEAInvalid;

    certalgtag = SECOID_GetAlgorithmTag(&(cert->subjectPublicKeyInfo.algorithm));
    PORT_Assert(certalgtag == SEC_OID_X942_DIFFIE_HELMAN_KEY);

    /* We really want to show our KEA tag as the key exchange algorithm tag. */
    encalgtag = SEC_OID_CMS_EPHEMERAL_STATIC_DIFFIE_HELLMAN;

    /* Get the public key of the recipient. */
    publickey = CERT_ExtractPublicKey(cert);
    if (publickey == NULL) goto loser;

    /* XXXX generate a DH key pair on a PKCS11 module (XXX which parameters?) */
    /* XXXX */ourCert = PK11_FindBestKEAMatch(cert, wincx);
    if (ourCert == NULL) goto loser;

    arena = PORT_NewArena(1024);
    if (arena == NULL) goto loser;

    /* While we're here, extract the key pair's public key data and copy it into */
    /* the outgoing parameters. */
    /* XXXX */ourPubKey = CERT_ExtractPublicKey(ourCert);
    if (ourPubKey == NULL)
    {
	goto loser;
    }
    SECITEM_CopyItem(arena, pubKey, /* XXX */&(ourPubKey->u.fortezza.KEAKey));
    SECKEY_DestroyPublicKey(ourPubKey); /* we only need the private key from now on */
    ourPubKey = NULL;

    /* Extract our private key in order to derive the KEA key. */
    ourPrivKey = PK11_FindKeyByAnyCert(ourCert,wincx);
    CERT_DestroyCertificate(ourCert); /* we're done with this */
    if (!ourPrivKey) goto loser;

    /* If ukm desired, prepare it - allocate enough space (filled with zeros). */
    if (ukm) {
	ukm->data = (unsigned char*)PORT_ArenaZAlloc(arena,/* XXXX */);
	ukm->len = /* XXXX */;
    }

    /* Generate the KEK (key exchange key) according to RFC2631 which we use
     * to wrap the bulk encryption key. */
    kek = PK11_PubDerive(ourPrivKey, publickey, PR_TRUE,
			 ukm, NULL,
			 /* XXXX */CKM_KEA_KEY_DERIVE, /* XXXX */CKM_SKIPJACK_WRAP,
			 CKA_WRAP, 0, wincx);

    SECKEY_DestroyPublicKey(publickey);
    SECKEY_DestroyPrivateKey(ourPrivKey);
    publickey = NULL;
    ourPrivKey = NULL;
    
    if (!kek)
	goto loser;

    /* allocate space for the encrypted CEK (bulk key) */
    encKey->data = (unsigned char*)PORT_ArenaAlloc(poolp, SMIME_FORTEZZA_MAX_KEY_SIZE);
    encKey->len = SMIME_FORTEZZA_MAX_KEY_SIZE;

    if (encKey->data == NULL)
    {
	PK11_FreeSymKey(kek);
	goto loser;
    }


    /* Wrap the bulk key using CMSRC2WRAP or CMS3DESWRAP, depending on the */
    /* bulk encryption algorithm */
    switch (/* XXXX */PK11_AlgtagToMechanism(enccinfo->encalg))
    {
    case /* XXXX */CKM_SKIPJACK_CFB8:
	err = PK11_WrapSymKey(/* XXXX */CKM_CMS3DES_WRAP, NULL, kek, bulkkey, encKey);
	whichKEA = NSSCMSKEAUsesSkipjack;
	break;
    case /* XXXX */CKM_SKIPJACK_CFB8:
	err = PK11_WrapSymKey(/* XXXX */CKM_CMSRC2_WRAP, NULL, kek, bulkkey, encKey);
	whichKEA = NSSCMSKEAUsesSkipjack;
	break;
    default:
	/* XXXX what do we do here? Neither RC2 nor 3DES... */
        err = SECFailure;
        /* set error */
	break;
    }

    PK11_FreeSymKey(kek);	/* we do not need the KEK anymore */
    if (err != SECSuccess)
	goto loser;

    PORT_Assert(whichKEA != NSSCMSKEAInvalid);

    /* see RFC2630 12.3.1.1 "keyEncryptionAlgorithm must be ..." */
    /* params is the DER encoded key wrap algorithm (with parameters!) (XXX) */
    params = SEC_ASN1EncodeItem(arena, NULL, &keaParams, sec_pkcs7_get_kea_template(whichKEA));
    if (params == NULL)
	goto loser;

    /* now set keyEncAlg */
    rv = SECOID_SetAlgorithmID(poolp, keyEncAlg, SEC_OID_CMS_EPHEMERAL_STATIC_DIFFIE_HELLMAN, params);
    if (rv != SECSuccess)
	goto loser;

    /* XXXXXXX this is not right yet */
loser:
    if (arena) {
	PORT_FreeArena(arena, PR_FALSE);
    }
    if (publickey) {
        SECKEY_DestroyPublicKey(publickey);
    }
    if (ourPrivKey) {
        SECKEY_DestroyPrivateKey(ourPrivKey);
    }
#endif
    return SECFailure;
}
예제 #14
0
SECStatus
NSS_CMSUtil_EncryptSymKey_MISSI(PLArenaPool *poolp, CERTCertificate *cert, PK11SymKey *bulkkey,
			SECOidTag symalgtag, SECItem *encKey, SECItem **pparams, void *pwfn_arg)
{
    SECOidTag certalgtag;	/* the certificate's encryption algorithm */
    SECOidTag encalgtag;	/* the algorithm used for key exchange/agreement */
    SECStatus rv = SECFailure;
    SECItem *params = NULL;
    SECStatus err;
    PK11SymKey *tek;
    CERTCertificate *ourCert;
    SECKEYPublicKey *ourPubKey, *publickey = NULL;
    SECKEYPrivateKey *ourPrivKey = NULL;
    NSSCMSKEATemplateSelector whichKEA = NSSCMSKEAInvalid;
    NSSCMSSMIMEKEAParameters keaParams;
    PLArenaPool *arena = NULL;
    extern const SEC_ASN1Template *nss_cms_get_kea_template(NSSCMSKEATemplateSelector whichTemplate);

    /* Clear keaParams, since cleanup code checks the lengths */
    (void) memset(&keaParams, 0, sizeof(keaParams));

    certalgtag = SECOID_GetAlgorithmTag(&(cert->subjectPublicKeyInfo.algorithm));
    PORT_Assert(certalgtag == SEC_OID_MISSI_KEA_DSS_OLD ||
		certalgtag == SEC_OID_MISSI_KEA_DSS ||
		certalgtag == SEC_OID_MISSI_KEA);

#define SMIME_FORTEZZA_RA_LENGTH 128
#define SMIME_FORTEZZA_IV_LENGTH 24
#define SMIME_FORTEZZA_MAX_KEY_SIZE 256

    /* We really want to show our KEA tag as the key exchange algorithm tag. */
    encalgtag = SEC_OID_NETSCAPE_SMIME_KEA;

    /* Get the public key of the recipient. */
    publickey = CERT_ExtractPublicKey(cert);
    if (publickey == NULL) goto loser;

    /* Find our own cert, and extract its keys. */
    ourCert = PK11_FindBestKEAMatch(cert, pwfn_arg);
    if (ourCert == NULL) goto loser;

    arena = PORT_NewArena(1024);
    if (arena == NULL)
	goto loser;

    ourPubKey = CERT_ExtractPublicKey(ourCert);
    if (ourPubKey == NULL) {
	CERT_DestroyCertificate(ourCert);
	goto loser;
    }

    /* While we're here, copy the public key into the outgoing
     * KEA parameters. */
    SECITEM_CopyItem(arena, &(keaParams.originatorKEAKey), &(ourPubKey->u.fortezza.KEAKey));
    SECKEY_DestroyPublicKey(ourPubKey);
    ourPubKey = NULL;

    /* Extract our private key in order to derive the KEA key. */
    ourPrivKey = PK11_FindKeyByAnyCert(ourCert, pwfn_arg);
    CERT_DestroyCertificate(ourCert); /* we're done with this */
    if (!ourPrivKey)
	goto loser;

    /* Prepare raItem with 128 bytes (filled with zeros). */
    keaParams.originatorRA.data = (unsigned char *)PORT_ArenaAlloc(arena,SMIME_FORTEZZA_RA_LENGTH);
    keaParams.originatorRA.len = SMIME_FORTEZZA_RA_LENGTH;

    /* Generate the TEK (token exchange key) which we use
     * to wrap the bulk encryption key. (keaparams.originatorRA) will be
     * filled with a random seed which we need to send to
     * the recipient. (user keying material in RFC2630/DSA speak) */
    tek = PK11_PubDerive(ourPrivKey, publickey, PR_TRUE,
			 &keaParams.originatorRA, NULL,
			 CKM_KEA_KEY_DERIVE, CKM_SKIPJACK_WRAP,
			 CKA_WRAP, 0,  pwfn_arg);

    SECKEY_DestroyPublicKey(publickey);
    SECKEY_DestroyPrivateKey(ourPrivKey);
    publickey = NULL;
    ourPrivKey = NULL;
    
    if (!tek)
	goto loser;

    /* allocate space for the wrapped key data */
    encKey->data = (unsigned char *)PORT_ArenaAlloc(poolp, SMIME_FORTEZZA_MAX_KEY_SIZE);
    encKey->len = SMIME_FORTEZZA_MAX_KEY_SIZE;

    if (encKey->data == NULL) {
	PK11_FreeSymKey(tek);
	goto loser;
    }

    /* Wrap the bulk key. What we do with the resulting data
       depends on whether we're using Skipjack to wrap the key. */
    switch (PK11_AlgtagToMechanism(symalgtag)) {
    case CKM_SKIPJACK_CBC64:
    case CKM_SKIPJACK_ECB64:
    case CKM_SKIPJACK_OFB64:
    case CKM_SKIPJACK_CFB64:
    case CKM_SKIPJACK_CFB32:
    case CKM_SKIPJACK_CFB16:
    case CKM_SKIPJACK_CFB8:
	/* SKIPJACK, we use the wrap mechanism because we can do it on the hardware */
	err = PK11_WrapSymKey(CKM_SKIPJACK_WRAP, NULL, tek, bulkkey, encKey);
	whichKEA = NSSCMSKEAUsesSkipjack;
	break;
    default:
	/* Not SKIPJACK, we encrypt the raw key data */
	keaParams.nonSkipjackIV.data = 
	  (unsigned char *)PORT_ArenaAlloc(arena, SMIME_FORTEZZA_IV_LENGTH);
	keaParams.nonSkipjackIV.len = SMIME_FORTEZZA_IV_LENGTH;
	err = PK11_WrapSymKey(CKM_SKIPJACK_CBC64, &keaParams.nonSkipjackIV, tek, bulkkey, encKey);
	if (err != SECSuccess)
	    goto loser;

	if (encKey->len != PK11_GetKeyLength(bulkkey)) {
	    /* The size of the encrypted key is not the same as
	       that of the original bulk key, presumably due to
	       padding. Encode and store the real size of the
	       bulk key. */
	    if (SEC_ASN1EncodeInteger(arena, &keaParams.bulkKeySize, PK11_GetKeyLength(bulkkey)) == NULL)
		err = (SECStatus)PORT_GetError();
	    else
		/* use full template for encoding */
		whichKEA = NSSCMSKEAUsesNonSkipjackWithPaddedEncKey;
	}
	else
	    /* enc key length == bulk key length */
	    whichKEA = NSSCMSKEAUsesNonSkipjack; 
	break;
    }

    PK11_FreeSymKey(tek);

    if (err != SECSuccess)
	goto loser;

    PORT_Assert(whichKEA != NSSCMSKEAInvalid);

    /* Encode the KEA parameters into the recipient info. */
    params = SEC_ASN1EncodeItem(poolp, NULL, &keaParams, nss_cms_get_kea_template(whichKEA));
    if (params == NULL)
	goto loser;

    /* pass back the algorithm params */
    *pparams = params;

    rv = SECSuccess;

loser:
    if (arena)
	PORT_FreeArena(arena, PR_FALSE);
    if (publickey)
        SECKEY_DestroyPublicKey(publickey);
    if (ourPrivKey)
        SECKEY_DestroyPrivateKey(ourPrivKey);
    return rv;
}
예제 #15
0
파일: authcert.c 프로젝트: 7kbird/chrome
/*
 * This callback used by SSL to pull client sertificate upon
 * server request
 */
SECStatus 
NSS_GetClientAuthData(void *                       arg, 
                      PRFileDesc *                 socket, 
		      struct CERTDistNamesStr *    caNames, 
		      struct CERTCertificateStr ** pRetCert, 
		      struct SECKEYPrivateKeyStr **pRetKey)
{
  CERTCertificate *  cert = NULL;
  SECKEYPrivateKey * privkey = NULL;
  char *             chosenNickName = (char *)arg;    /* CONST */
  void *             proto_win  = NULL;
  SECStatus          rv         = SECFailure;
  
  proto_win = SSL_RevealPinArg(socket);
  
  if (chosenNickName) {
    cert = CERT_FindUserCertByUsage(CERT_GetDefaultCertDB(),
                                    chosenNickName, certUsageSSLClient,
                                    PR_FALSE, proto_win);	
    if ( cert ) {
      privkey = PK11_FindKeyByAnyCert(cert, proto_win);
      if ( privkey ) {
	rv = SECSuccess;
      } else {
	CERT_DestroyCertificate(cert);
      }
    }
  } else { /* no name given, automatically find the right cert. */
    CERTCertNicknames * names;
    int                 i;
      
    names = CERT_GetCertNicknames(CERT_GetDefaultCertDB(),
				  SEC_CERT_NICKNAMES_USER, proto_win);
    if (names != NULL) {
      for (i = 0; i < names->numnicknames; i++) {
	cert = CERT_FindUserCertByUsage(CERT_GetDefaultCertDB(),
                            names->nicknames[i], certUsageSSLClient,
                            PR_FALSE, proto_win);	
	if ( !cert )
	  continue;
	/* Only check unexpired certs */
	if (CERT_CheckCertValidTimes(cert, PR_Now(), PR_TRUE) != 
	    secCertTimeValid ) {
	  CERT_DestroyCertificate(cert);
	  continue;
	}
	rv = NSS_CmpCertChainWCANames(cert, caNames);
	if ( rv == SECSuccess ) {
	  privkey = PK11_FindKeyByAnyCert(cert, proto_win);
	  if ( privkey )
	    break;
	}
	rv = SECFailure;
	CERT_DestroyCertificate(cert);
      } 
      CERT_FreeNicknames(names);
    }
  }
  if (rv == SECSuccess) {
    *pRetCert = cert;
    *pRetKey  = privkey;
  }
  return rv;
}
예제 #16
0
/*
 * NSS_CMSSignerInfo_Sign - sign something
 *
 */
SECStatus
NSS_CMSSignerInfo_Sign(NSSCMSSignerInfo *signerinfo, SECItem *digest, 
                       SECItem *contentType)
{
    CERTCertificate *cert;
    SECKEYPrivateKey *privkey = NULL;
    SECOidTag digestalgtag;
    SECOidTag pubkAlgTag;
    SECItem signature = { 0 };
    SECStatus rv;
    PLArenaPool *poolp, *tmppoolp = NULL;
    SECAlgorithmID *algID, freeAlgID;
    CERTSubjectPublicKeyInfo *spki;

    PORT_Assert (digest != NULL);

    poolp = signerinfo->cmsg->poolp;

    switch (signerinfo->signerIdentifier.identifierType) {
    case NSSCMSSignerID_IssuerSN:
        cert = signerinfo->cert;

        privkey = PK11_FindKeyByAnyCert(cert, signerinfo->cmsg->pwfn_arg);
        if (privkey == NULL)
	    goto loser;
        algID = &cert->subjectPublicKeyInfo.algorithm;
        break;
    case NSSCMSSignerID_SubjectKeyID:
        privkey = signerinfo->signingKey;
        signerinfo->signingKey = NULL;
        spki = SECKEY_CreateSubjectPublicKeyInfo(signerinfo->pubKey);
        SECKEY_DestroyPublicKey(signerinfo->pubKey);
        signerinfo->pubKey = NULL;
        SECOID_CopyAlgorithmID(NULL, &freeAlgID, &spki->algorithm);
        SECKEY_DestroySubjectPublicKeyInfo(spki); 
        algID = &freeAlgID;
        break;
    default:
        goto loser;
    }
    digestalgtag = NSS_CMSSignerInfo_GetDigestAlgTag(signerinfo);
    /*
     * XXX I think there should be a cert-level interface for this,
     * so that I do not have to know about subjectPublicKeyInfo...
     */
    pubkAlgTag = SECOID_GetAlgorithmTag(algID);
    if (signerinfo->signerIdentifier.identifierType == NSSCMSSignerID_SubjectKeyID) {
      SECOID_DestroyAlgorithmID(&freeAlgID, PR_FALSE);
    }

    if (signerinfo->authAttr != NULL) {
	SECOidTag signAlgTag;
	SECItem encoded_attrs;

	/* find and fill in the message digest attribute. */
	rv = NSS_CMSAttributeArray_SetAttr(poolp, &(signerinfo->authAttr), 
	                       SEC_OID_PKCS9_MESSAGE_DIGEST, digest, PR_FALSE);
	if (rv != SECSuccess)
	    goto loser;

	if (contentType != NULL) {
	    /* if the caller wants us to, find and fill in the content type attribute. */
	    rv = NSS_CMSAttributeArray_SetAttr(poolp, &(signerinfo->authAttr), 
	                    SEC_OID_PKCS9_CONTENT_TYPE, contentType, PR_FALSE);
	    if (rv != SECSuccess)
		goto loser;
	}

	if ((tmppoolp = PORT_NewArena (1024)) == NULL) {
	    PORT_SetError(SEC_ERROR_NO_MEMORY);
	    goto loser;
	}

	/*
	 * Before encoding, reorder the attributes so that when they
	 * are encoded, they will be conforming DER, which is required
	 * to have a specific order and that is what must be used for
	 * the hash/signature.  We do this here, rather than building
	 * it into EncodeAttributes, because we do not want to do
	 * such reordering on incoming messages (which also uses
	 * EncodeAttributes) or our old signatures (and other "broken"
	 * implementations) will not verify.  So, we want to guarantee
	 * that we send out good DER encodings of attributes, but not
	 * to expect to receive them.
	 */
	if (NSS_CMSAttributeArray_Reorder(signerinfo->authAttr) != SECSuccess)
	    goto loser;

	encoded_attrs.data = NULL;
	encoded_attrs.len = 0;
	if (NSS_CMSAttributeArray_Encode(tmppoolp, &(signerinfo->authAttr), 
	                &encoded_attrs) == NULL)
	    goto loser;

	signAlgTag = SEC_GetSignatureAlgorithmOidTag(privkey->keyType, 
                                                     digestalgtag);
	if (signAlgTag == SEC_OID_UNKNOWN) {
	    PORT_SetError(SEC_ERROR_INVALID_ALGORITHM);
	    goto loser;
	}

	rv = SEC_SignData(&signature, encoded_attrs.data, encoded_attrs.len, 
	                  privkey, signAlgTag);
	PORT_FreeArena(tmppoolp, PR_FALSE); /* awkward memory management :-( */
	tmppoolp = 0;
    } else {
	rv = SGN_Digest(privkey, digestalgtag, &signature, digest);
    }
    SECKEY_DestroyPrivateKey(privkey);
    privkey = NULL;

    if (rv != SECSuccess)
	goto loser;

    if (SECITEM_CopyItem(poolp, &(signerinfo->encDigest), &signature) 
          != SECSuccess)
	goto loser;

    SECITEM_FreeItem(&signature, PR_FALSE);

    if (SECOID_SetAlgorithmID(poolp, &(signerinfo->digestEncAlg), pubkAlgTag, 
                              NULL) != SECSuccess)
	goto loser;

    return SECSuccess;

loser:
    if (signature.len != 0)
	SECITEM_FreeItem (&signature, PR_FALSE);
    if (privkey)
	SECKEY_DestroyPrivateKey(privkey);
    if (tmppoolp)
	PORT_FreeArena(tmppoolp, PR_FALSE);
    return SECFailure;
}
/*
 * objectType is bitwise-OR of all the object types you want to traverse.
 */
static PRStatus
traverseTokenObjects
    (JNIEnv *env, PK11SlotInfo *slot, TokenObjectTraversalCallback cb,
        int objectTypes, void *data)
{
    PRStatus status = PR_FAILURE;
    JSSTraversalStatus travstat = INIT_TRAVSTAT;
    SECKEYPrivateKeyList* privkList = NULL;
    SECKEYPublicKeyList* pubkList = NULL;
    PK11SymKey *symKey = NULL;
    CERTCertList *certList = NULL;
    SECStatus secstat;

    /*
     * Get all private keys
     */
    if( objectTypes & PRIVKEY ) {
        SECKEYPrivateKeyListNode *node = NULL;

        privkList = PK11_ListPrivKeysInSlot(slot, NULL /*nickname*/,
                            NULL /*wincx*/);
        if( privkList != NULL ) {

            for( node = PRIVKEY_LIST_HEAD(privkList);
                ! PRIVKEY_LIST_END(node, privkList);
                node = PRIVKEY_LIST_NEXT(node) )
            {
                travstat = cb(env, slot, PRIVKEY, (void*) node->key, data);
                if( travstat.status == PR_FAILURE ) {
                    goto finish;
                }
                if( travstat.deleteIt ) {
                    /* Setting "force" to PR_FALSE means that if there is a
                     * matching cert, the key won't be deleted.
                     * If the KeyStore API is being followed, the cert
                     * should have the same nickname as the key. So
                     * both will get deleted when we scan for matching
                     * certs later.
                     */
                    PK11_DeleteTokenPrivateKey(node->key, PR_FALSE /*force*/);
                    node->key = NULL;
                    PR_REMOVE_LINK(&node->links);
                    /* we don't free node because it is allocated from
                     * the list's arena and will get freed when the list
                     * is freed. */
                }
                if( travstat.stopIterating ) {
                    goto stop_early;
                }
            }
        }
    }

    /*
     * Get all symmetric keys
     */
    if(objectTypes & SYMKEY) {
        /* this function returns a chained list of symmetric keys */
        symKey = PK11_ListFixedKeysInSlot(slot, NULL /*nickname*/,
                    NULL/*wincx*/);

        while( symKey != NULL ) {
            PK11SymKey *deadKey;
            travstat = cb(env, slot, SYMKEY, (void*) symKey, data);
            if( travstat.status != PR_SUCCESS ) {
                goto finish;
            }
            if( travstat.deleteIt ) {
                /* this just deletes the PKCS #11 object. The data structure
                 * is NOT deleted. */
                PK11_DeleteTokenSymKey(symKey);
            }
            if( travstat.stopIterating ) {
                goto stop_early;
            }

            deadKey = symKey;
            symKey = PK11_GetNextSymKey(symKey);
            PK11_FreeSymKey(deadKey);
        }
    }

    /*
     * get all public keys
     */
    if( objectTypes & PUBKEY ) {
        SECKEYPublicKeyListNode *node = NULL;

        pubkList = PK11_ListPublicKeysInSlot(slot, NULL /*nickname*/);
        if( pubkList != NULL ) {

            for( node = PUBKEY_LIST_HEAD(pubkList);
                ! PUBKEY_LIST_END(node, pubkList);
                node = PUBKEY_LIST_NEXT(node) )
            {
                if( node->key == NULL ) {
                    /* workaround NSS bug 130699: PK11_ListPublicKeysInSlot
                     * returns NULL if slot contains token symmetric key */
                    continue;
                }
                travstat = cb(env, slot, PUBKEY, (void*) node->key, data);
                if( travstat.status != PR_SUCCESS ) {
                    goto finish;
                }
                if( travstat.deleteIt ) {
                    /* XXX!!!
                     * Workaround for 125408: PK11_DeleteTokenPublic key asserts
                     * Don't delete the public key.

                     * PK11_DeleteTokenPublicKey(node->key);
                     * node->key = NULL;
                     * PR_REMOVE_LINK(&node->links);
                     */
                    /* node is allocated from the list's arena, it will get
                     * freed with the list */
                }
                if( travstat.stopIterating ) {
                    goto stop_early;
                }
            }

            /*
             * XXX!!!
             * Destroy the list before we move on. Why bother, since we'll
             * do it anyway in the finish block? Because of bug 125408.
             * If we delete the cert and private key while traversing certs,
             * we'll delete the public key too, and then we'll crash when
             * we free the same public key while destroying the list.
             */
            SECKEY_DestroyPublicKeyList(pubkList);
            pubkList = NULL;
        }
    }

    /*
     * Get all certs
     */
    if( objectTypes & CERT ) {
        CERTCertListNode *node = NULL;

        certList = PK11_ListCertsInSlot(slot);
        if( certList == NULL ) {
            JSS_throwMsgPrErr(env, TOKEN_EXCEPTION,
                "Failed to list certificates on token");
            goto finish;
        }

        for( node = CERT_LIST_HEAD(certList);
             ! CERT_LIST_END(node, certList);
             node = CERT_LIST_NEXT(node) )
        {
            travstat = cb(env, slot, CERT, (void*) node->cert, data);
            if( travstat.status != PR_SUCCESS ) {
                goto finish;
            }
            if( travstat.deleteIt ) {
                /*
                 * Since, in a KeyStore, certs and private keys go together,
                 * remove the private key too, if there is one.
                 *
                 * The hack here is that PK11_DeleteTokenCertAndKey will
                 * not delete the cert if there is no matching private key.
                 * We want to the cert to be deleted even if the key isn't
                 * there. So we only call that function if we're sure the
                 * key is there. Otherwise we delete the cert directly.
                 */
                SECKEYPrivateKey *privKey = PK11_FindKeyByAnyCert(node->cert, 
                    NULL /*wincx*/);
                PRBool keyPresent = (privKey != NULL);
                SECKEY_DestroyPrivateKey(privKey);
                if( keyPresent ) {
                    PK11_DeleteTokenCertAndKey(node->cert, NULL /*wincx*/);
                } else {
                    SEC_DeletePermCertificate(node->cert);
                }
                PR_REMOVE_LINK(&node->links);
                /* node is allocated from the list's arena, it will get freed
                 * with the list */
            }
            if( travstat.stopIterating ) {
                goto stop_early;
            }
        }
    }

stop_early:
    status = PR_SUCCESS;
finish:
    if( privkList != NULL ) {
        SECKEY_DestroyPrivateKeyList(privkList);
    }
    if( pubkList != NULL ) {
        SECKEY_DestroyPublicKeyList(pubkList);
    }
    while( symKey != NULL ) {
        PK11SymKey *deadKey;
        deadKey = symKey;
        symKey = PK11_GetNextSymKey(symKey);
        PK11_FreeSymKey(deadKey);
    }
    if( certList != NULL ) {
        CERT_DestroyCertList(certList);
    }
    return status;
}
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;
}
예제 #19
0
int FileSSLDoublePoint_main(char * strUserPin, char * strNickName)
{
#if 1
    int isServer = 0;
    
    SECStatus rv = SECSuccess;
    
    
    char * buffer = malloc(1024 * 1024);
    
    
    PR_Init(PR_SYSTEM_THREAD, PR_PRIORITY_NORMAL, 1);
    
    PK11_SetPasswordFunc(GetModulePassword);
    rv = NSS_Initialize(GetSystemDBDir(),
                        "", "",
                        "secmod.db", 0);
    
    
    rv = SSL_OptionSetDefault(SSL_SECURITY, PR_TRUE);
    rv = SSL_OptionSetDefault(SSL_SOCKS, PR_TRUE);
    rv = SSL_OptionSetDefault(SSL_ENABLE_SSL2, PR_TRUE);
    rv = SSL_OptionSetDefault(SSL_ENABLE_SSL3, PR_TRUE);
    rv = SSL_OptionSetDefault(SSL_ENABLE_FDX, PR_TRUE);
    
    rv = SSL_OptionSetDefault(SSL_ENABLE_TLS, PR_TRUE);
    
    rv = NSS_SetDomesticPolicy();
    rv = NSS_SetExportPolicy();
    rv = NSS_SetFrancePolicy();
    //    rv = SSL_CipherPolicySet();
    
    
    
    SSL_ClearSessionCache();
    
    rv = SSL_ConfigServerSessionIDCache(10, 30 , 30, ".");
    
    
    PRFileDesc * tcp_socket = PR_NewTCPSocket();
    
    PRFileDesc * ssl_socket = SSL_ImportFD(NULL,tcp_socket);
    
    if (isServer) {
        
        CERTCertDBHandle *certHandle;
        
        certHandle = CERT_GetDefaultCertDB();
        
        char * nickname = "4914afeedee988071490b98f1120ddac_e73f20c7-176d-4342-ac89-ea7c00bb570a";/*nickname*/
        
        CERTCertificate* cert = NULL;
        cert = CERT_FindCertByNicknameOrEmailAddr(certHandle, nickname);
        
        
        SECKEYPrivateKey *prvKey = NULL;
        
        prvKey = PK11_FindKeyByAnyCert(cert, NULL);
        
        rv = SSL_ConfigSecureServer(ssl_socket, cert,prvKey,ssl_kea_rsa);
        
        
        PRNetAddr netAddr;
        
        PRNetAddr netAddrLocal;
        
        
        rv = PR_InitializeNetAddr(0, 8888, &netAddr);
        
        
        rv = PR_StringToNetAddr("127.0.0.1", &netAddrLocal);
        
        rv = PR_Bind(tcp_socket,&netAddr);
        rv = PR_Listen(tcp_socket, 100);
        
        
        while (1) {
            PRFileDesc * client = PR_Accept(tcp_socket, &netAddr, 6000000);
            PRNetAddr addr;
            
            
            rv = PR_GetSockName(client, &addr);
            
            rv = SSL_ForceHandshake(client);
            
            
            rv = PR_Write(client,"123", 4);
            
            sleep(1);
        }
        
    }
    else
    {
        rv = SSL_AuthCertificateHook(ssl_socket, OwnAuthCertHandler, NULL);
        char * nickname = "nickname";/*nickname*/
        
        rv = SSL_SetURL(ssl_socket, "192.168.18.22");
        
        char * str = malloc(1024) ;

		memset(str, 0, 1024);
        
        strcpy(str ,"GET /test/test2.html HTTP/1.1\r\n");//注意\r\n为回车换行
        //        str = [str stringByAppendingString:@"Accept-Language: zh-cn\r\n"];
        //        str = [str stringByAppendingString:@"Connection: Keep-Alive\r\n"];
        //str = [str stringByAppendingString:@"Host: 192.168.0.106\r\n"];
        strcat(str ,"Host: 192.168.18.22:8443\r\n");
        //        str = [str stringByAppendingString:@"Content-Length: 0\r\n"];
        strcat(str ,"\r\n");
        //        str = [str stringByAppendingString:@"userName=liqiangqiang&password=new_andy\r\n"];
        //        str = [str stringByAppendingString:@"\r\n"];
        
        PRNetAddr netAddr;
        
        
        rv = PR_StringToNetAddr("192.168.18.22", &netAddr);
        
        rv = PR_InitializeNetAddr(0, 8443, &netAddr);
        
        //        rv = PR_GetHostByName();
        //        PR_EnumerateHostEnt
        
        
        rv = PR_Connect(tcp_socket,&netAddr, 300000);

		FILE_LOG_NUMBER("/sdcard/ssl.log", rv);

        rv = SSL_GetClientAuthDataHook(ssl_socket,NSS_GetClientAuthData,strNickName);

		FILE_LOG_NUMBER("/sdcard/ssl.log", rv);
        
        rv = SSL_ForceHandshake(ssl_socket);
        
		FILE_LOG_NUMBER("/sdcard/ssl.log", rv);
        
        rv = PR_Write(tcp_socket, str, strlen(str));
        
		FILE_LOG_NUMBER("/sdcard/ssl.log", rv);

        rv = PR_Read(tcp_socket,buffer, 1024 * 1024);

		FILE_LOG_NUMBER("/sdcard/ssl.log", rv);
        
        FILE * file = fopen("/sdcard/ssl_read.txt", "wb");
        
        //fwrite(buffer, 1, rv, file);

        //rv = PR_Read(tcp_socket,buffer, 1024 * 1024);
        
        fwrite(buffer, 1, rv, file);
        
        fclose(file);
        
        sleep(1);
        
        
        rv = SSL_InvalidateSession(ssl_socket);
        
        rv = PR_Shutdown(tcp_socket, PR_SHUTDOWN_BOTH);
        
        rv = PR_Close(tcp_socket);
        
        rv = ssl_FreeSessionCacheLocks();
        
        rv = NSS_Shutdown();
        
    }
#endif
    
    return 0;
}
예제 #20
0
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.
  ScopedCERTCertificateList 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 = reinterpret_cast<CERTCertificateList*>(
      PORT_ArenaAlloc(arena, 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;
  }

  ScopedSECKEYPrivateKey key(PK11_FindKeyByAnyCert(cert, nullptr));
  if (!key) {
    PrintPRError("PK11_FindKeyByAnyCert failed");
    return SECFailure;
  }

  SSLKEAType certKEA = NSS_FindCertKEAType(cert);

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

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

  if (keaOut) {
    *keaOut = certKEA;
  }

  return SECSuccess;
}
예제 #21
0
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;
}
예제 #22
0
/* Function: SECStatus ownGetClientAuthData()
 *
 * Purpose: This callback is used by SSL to pull client certificate 
 * information upon server request.
 */
SECStatus 
myGetClientAuthData(void *arg,
                    PRFileDesc *socket,
                    struct CERTDistNamesStr *caNames,
                    struct CERTCertificateStr **pRetCert,
                    struct SECKEYPrivateKeyStr **pRetKey) 
{

    CERTCertificate *  cert;
    SECKEYPrivateKey * privKey;
    char *             chosenNickName = (char *)arg;
    void *             proto_win      = NULL;
    SECStatus          secStatus      = SECFailure;

    proto_win = SSL_RevealPinArg(socket);

    if (chosenNickName) {
	cert = PK11_FindCertFromNickname(chosenNickName, proto_win);
	if (cert) {
	    privKey = PK11_FindKeyByAnyCert(cert, proto_win);
	    if (privKey) {
		secStatus = SECSuccess;
	    } else {
		CERT_DestroyCertificate(cert);
	    }
	}
    } else { /* no nickname given, automatically find the right cert */
	CERTCertNicknames *names;
	int                i;

	names = CERT_GetCertNicknames(CERT_GetDefaultCertDB(), 
				      SEC_CERT_NICKNAMES_USER, proto_win);

	if (names != NULL) {
	    for(i = 0; i < names->numnicknames; i++ ) {

		cert = PK11_FindCertFromNickname(names->nicknames[i], 
						 proto_win);
		if (!cert) {
		    continue;
		}

		/* Only check unexpired certs */
		if (CERT_CheckCertValidTimes(cert, PR_Now(), PR_FALSE)
		      != secCertTimeValid ) {
		    CERT_DestroyCertificate(cert);
		    continue;
		}

		secStatus = NSS_CmpCertChainWCANames(cert, caNames);
		if (secStatus == SECSuccess) {
		    privKey = PK11_FindKeyByAnyCert(cert, proto_win);
		    if (privKey) {
			break;
		    }
		    secStatus = SECFailure;
		}
		CERT_DestroyCertificate(cert);
	    } /* for loop */
	    CERT_FreeNicknames(names);
	}
    }

    if (secStatus == SECSuccess) {
	*pRetCert = cert;
	*pRetKey  = privKey;
    }

    return secStatus;
}