Esempio n. 1
0
 virtual void SetUp() {
     std::ofstream cert(certfname());
     cert <<
          "-----BEGIN CERTIFICATE-----\n"
          "MIIC2DCCAkGgAwIBAgIJALptEXUhC5kTMA0GCSqGSIb3DQEBBQUAMFIxCzAJBgNV\n"
          "BAYTAkFVMRMwEQYDVQQIEwpTb21lLVN0YXRlMRYwFAYDVQQKEw1NeUNvbXBhbnlO\n"
          "YW1lMRYwFAYDVQQDEw1NeUNvbXBhbnlOYW1lMB4XDTA4MDcxMDA5MzMxNFoXDTA5\n"
          "MDcxMDA5MzMxNFowUjELMAkGA1UEBhMCQVUxEzARBgNVBAgTClNvbWUtU3RhdGUx\n"
          "FjAUBgNVBAoTDU15Q29tcGFueU5hbWUxFjAUBgNVBAMTDU15Q29tcGFueU5hbWUw\n"
          "gZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAMMcKQ/dau+wJDPaXHPndsgCKQgs\n"
          "AUMnqSw4DZoapBlWJ1J5CvEIJJIqnFHbxk9kDAz1g9zgwSMJE311hC0tRw6idSDh\n"
          "7CznKdgJaD/Hp7Y+vAK7yr6H9vHKDZA6wRhr99bjuZcqQS87mTH1QT86xwJGrttP\n"
          "CSYNiiB9NHV7jyRZAgMBAAGjgbUwgbIwHQYDVR0OBBYEFN2yRL8s0pU48FubdhJK\n"
          "gBds6zphMIGCBgNVHSMEezB5gBTdskS/LNKVOPBbm3YSSoAXbOs6YaFWpFQwUjEL\n"
          "MAkGA1UEBhMCQVUxEzARBgNVBAgTClNvbWUtU3RhdGUxFjAUBgNVBAoTDU15Q29t\n"
          "cGFueU5hbWUxFjAUBgNVBAMTDU15Q29tcGFueU5hbWWCCQC6bRF1IQuZEzAMBgNV\n"
          "HRMEBTADAQH/MA0GCSqGSIb3DQEBBQUAA4GBAHrEQf8iDUYeTO2jx/AlVsYC1nx6\n"
          "zEh1kPtdcN57hVpnIooP9NlhZBJ/Cc7DtJikpZhHU4AJdZx9O5uenS06fFdjHD0X\n"
          "1zWzI27GpT4kBwQPygexRjeb+6JopwibigmVIxE+u2dLwrQzrCOXxxuYDHgfZZmv\n"
          "WvKs6j3JlDKL3hS9\n"
          "-----END CERTIFICATE-----\n"
          ;
     std::ofstream key(keyfname());
     key <<
         "-----BEGIN RSA PRIVATE KEY-----\n"
         "MIICXAIBAAKBgQDDHCkP3WrvsCQz2lxz53bIAikILAFDJ6ksOA2aGqQZVidSeQrx\n"
         "CCSSKpxR28ZPZAwM9YPc4MEjCRN9dYQtLUcOonUg4ews5ynYCWg/x6e2PrwCu8q+\n"
         "h/bxyg2QOsEYa/fW47mXKkEvO5kx9UE/OscCRq7bTwkmDYogfTR1e48kWQIDAQAB\n"
         "AoGAYlt538OROw+i0HkODmfrG1zrbnEwmbgOsnn3cW5ot1UVMaBPgb7HIOBWOXX/\n"
         "fNpEsOu788dh1dWne6GYZmXi4X5E2uLksnD9CfD356X8RjK8fX3un8XpYE64X3FF\n"
         "9+cdSJdklbSDPPGGzjkwTkAzF68hnp0uYvt4t3KrAARpRWECQQDopNSBPtKN7Fr2\n"
         "H8wNMH8fyPs4Rknt6wfWvA5CNQvI6M6EkLXpK8ae2su6TAaytcNboYW43NdFlpNd\n"
         "y6Kj8AOdAkEA1rKsjk3w8DgOrCZOhSvJ22ggDuY2+vUxcFRzb+lxSJd9H4i826l1\n"
         "aDmuriUweBBRHDr9ycV3YpX4rcOl45887QJAQ1UxjBa6qgj2arXZQRgAMxrgWvE9\n"
         "BHc51ZSoK9Fej8+RthyMCeh5nBCHVmwapC6nVCXzpgWE6Mcj78m4UOpuoQJAPV2c\n"
         "jKAiecbMCtB4KQA3FgtQ/nE2zcw/cUfyJs6mnoUOMnE26eIpuLyj/QqMLAUd6d/C\n"
         "omValkcfaSs+wyzEkQJBANpYQPve57avZiw9U20L77VXq0aM4+Dcy1qPmxDI9vss\n"
         "SnaQRfzJBhk+LkyLt1CiSysrp9RcsxHN0zvXl98wCNw=\n"
         "-----END RSA PRIVATE KEY-----\n"
         ;
 }
Esempio n. 2
0
SECStatus
BuildCertChain(TrustDomain& trustDomain,
               const CERTCertificate* nssCert,
               PRTime time,
               EndEntityOrCA endEntityOrCA,
               /*optional*/ KeyUsages requiredKeyUsagesIfPresent,
               /*optional*/ KeyPurposeId requiredEKUIfPresent,
               const CertPolicyId& requiredPolicy,
               /*optional*/ const SECItem* stapledOCSPResponse,
               /*out*/ ScopedCERTCertList& results)
{
  if (!nssCert) {
    PR_NOT_REACHED("null cert passed to BuildCertChain");
    PR_SetError(SEC_ERROR_INVALID_ARGS, 0);
    return SECFailure;
  }

  // XXX: Support the legacy use of the subject CN field for indicating the
  // domain name the certificate is valid for.
  BackCert::IncludeCN includeCN
    = endEntityOrCA == EndEntityOrCA::MustBeEndEntity &&
      requiredEKUIfPresent == KeyPurposeId::id_kp_serverAuth
    ? BackCert::IncludeCN::Yes
    : BackCert::IncludeCN::No;

  BackCert cert(nullptr, includeCN);
  Result rv = cert.Init(nssCert->derCert);
  if (rv != Success) {
    return SECFailure;
  }

  rv = BuildForward(trustDomain, cert, time, endEntityOrCA,
                    requiredKeyUsagesIfPresent, requiredEKUIfPresent,
                    requiredPolicy, stapledOCSPResponse, 0, results);
  if (rv != Success) {
    results = nullptr;
    return SECFailure;
  }

  return SECSuccess;
}
Esempio n. 3
0
const QgsPkiBundle QgsPkiBundle::fromPkcs12Paths( const QString &bundlepath,
    const QString &bundlepass )
{
  QgsPkiBundle pkibundle;
  if ( QCA::isSupported( "pkcs12" )
       && !bundlepath.isEmpty()
       && ( bundlepath.endsWith( ".p12", Qt::CaseInsensitive )
            || bundlepath.endsWith( ".pfx", Qt::CaseInsensitive ) )
       && QFile::exists( bundlepath ) )
  {
    QCA::SecureArray passarray;
    if ( !bundlepass.isNull() )
      passarray = QCA::SecureArray( bundlepass.toUtf8() );
    QCA::ConvertResult res;
    QCA::KeyBundle bundle( QCA::KeyBundle::fromFile( bundlepath, passarray, &res, QString( "qca-ossl" ) ) );
    if ( res == QCA::ConvertGood && !bundle.isNull() )
    {
      QCA::CertificateChain cert_chain( bundle.certificateChain() );
      QSslCertificate cert( cert_chain.primary().toPEM().toAscii() );
      if ( !cert.isNull() )
      {
        pkibundle.setClientCert( cert );
      }
      QSslKey cert_key( bundle.privateKey().toPEM().toAscii(), QSsl::Rsa, QSsl::Pem, QSsl::PrivateKey, QByteArray() );
      if ( !cert_key.isNull() )
      {
        pkibundle.setClientKey( cert_key );
      }

      if ( cert_chain.size() > 1 )
      {
        QList<QSslCertificate> ca_chain;
        Q_FOREACH ( const QCA::Certificate& ca_cert, cert_chain )
        {
          if ( ca_cert != cert_chain.primary() )
          {
            ca_chain << QSslCertificate( ca_cert.toPEM().toAscii() );
          }
        }
        pkibundle.setCaChain( ca_chain );
      }
Esempio n. 4
0
ChooseCertificateScreen::ChooseCertificateScreen()
	: CursesContainer(mainScreen),
	  CursesKeyHandler(PRI_SCREENHANDLER),
	  title(this, _("Certificates")),
	  menu(this)
{
	setRow(2);
	setAlignment(Curses::PARENTCENTER);
	title.setAlignment(Curses::PARENTCENTER);

	menu.setRow(2);

	std::map<std::string, Certificates::cert>::iterator p;

	for (p=myServer::certs->certs.begin();
	     p != myServer::certs->certs.end(); ++p)
	{
		certs.push_back(cert(this, p->second.name, p->first));
		menu.addPrompt(NULL, &certs.back());
	}
}
Esempio n. 5
0
bool OpenSSLContext::setClientCertificate(CertificateWithKey::ref certificate) {
	boost::shared_ptr<PKCS12Certificate> pkcs12Certificate = boost::dynamic_pointer_cast<PKCS12Certificate>(certificate);
	if (!pkcs12Certificate || pkcs12Certificate->isNull()) {
		return false;
	}

	// Create a PKCS12 structure
	BIO* bio = BIO_new(BIO_s_mem());
	BIO_write(bio, vecptr(pkcs12Certificate->getData()), pkcs12Certificate->getData().size());
	boost::shared_ptr<PKCS12> pkcs12(d2i_PKCS12_bio(bio, NULL), PKCS12_free);
	BIO_free(bio);
	if (!pkcs12) {
		return false;
	}

	// Parse PKCS12
	X509 *certPtr = 0;
	EVP_PKEY* privateKeyPtr = 0;
	STACK_OF(X509)* caCertsPtr = 0;
	int result = PKCS12_parse(pkcs12.get(), reinterpret_cast<const char*>(vecptr(pkcs12Certificate->getPassword())), &privateKeyPtr, &certPtr, &caCertsPtr);
	if (result != 1) { 
		return false;
	}
	boost::shared_ptr<X509> cert(certPtr, X509_free);
	boost::shared_ptr<EVP_PKEY> privateKey(privateKeyPtr, EVP_PKEY_free);
	boost::shared_ptr<STACK_OF(X509)> caCerts(caCertsPtr, freeX509Stack);

	// Use the key & certificates
	if (SSL_CTX_use_certificate(context_, cert.get()) != 1) {
		return false;
	}
	if (SSL_CTX_use_PrivateKey(context_, privateKey.get()) != 1) {
		return false;
	}
	for (int i = 0;  i < sk_X509_num(caCerts.get()); ++i) {
		SSL_CTX_add_extra_chain_cert(context_, sk_X509_value(caCerts.get(), i));
	}
	return true;
}
Esempio n. 6
0
void SettingsDialog::validateP12Cert()
{
	d->showP12Cert->setEnabled( false );
	d->p12Error->clear();
	QFile f( d->p12Cert->text() );
	if( !f.open( QIODevice::ReadOnly ) )
		return;

	PKCS12Certificate cert( &f, d->p12Pass->text().toLatin1() );
	switch( cert.error() )
	{
	case PKCS12Certificate::NullError:
		d->showP12Cert->setEnabled( !cert.isNull() );
		break;
	case PKCS12Certificate::InvalidPasswordError:
		d->p12Error->setText( tr("Invalid password") );
		break;
	default:
		d->p12Error->setText( tr("Server access certificate error: %1").arg( cert.errorString() ) );
		break;
	}
}
// -----------------------------------------------------------------------------
// RoapStorageClient::VerifyL
// -----------------------------------------------------------------------------
//
EXPORT_C TBool Roap::RRoapStorageClient::VerifyL(
    const TDesC8& aSignature,
    const TDesC8& aHash,
    const RPointerArray<HBufC8>& aCertificateChain )
    {
    CRSAPublicKey* publicKey( NULL );
    TBool r( ETrue );
    CX509Certificate* cert( NULL );
    TX509KeyFactory factory;

    if ( aCertificateChain.Count() <= 0 )
        {
        User::Leave( KErrArgument );
        }
    cert = CX509Certificate::NewLC( *aCertificateChain[0] );
    publicKey = factory.RSAPublicKeyL( cert->PublicKey().KeyData() );
    CleanupStack::PushL( publicKey );
    r = OmaCrypto::RsaPssVerifyHashL( publicKey, aSignature, aHash );
    CleanupStack::PopAndDestroy( publicKey );
    CleanupStack::PopAndDestroy( cert );
    return r;
    }
/** \brief Return true if the router_lident_t is_sane() false otherwise
 */
bool	router_lident_t::is_sane()	const throw()
{
	// sanity check - the router_lident_t MUST be either selfsigned/authsigned/nonesigned
	DBG_ASSERT( is_selfsigned() || is_authsigned() || is_nonesigned() );
	// sanity check - the router_peerid_t MUST NOT be null
	DBG_ASSERT( !peerid().is_null() );
	// sanity check - the x509_privkey_t MUST NOT be null
	DBG_ASSERT( !privkey().is_null() );
	// sanity check - the x509_cert_t MUST NOT be null
	DBG_ASSERT( !cert().is_null() );
	// sanity check - m_dnsname MUST be either is_host_only() or is_fully_qualified()
	DBG_ASSERT( dnsname().is_host_only() || dnsname().is_fully_qualified() );
	// sanity check - if the dnsname() is_selfsigned_ok
	if( dnsname().is_selfsigned_ok() ){
		// sanity check - the subject_name MUST be the peerid canonical string
		DBG_ASSERT( peerid() == router_peerid_t::from_canonical_string(cert().subject_name()) );
		// sanity check - the cert MUST be selfsigned
		DBG_ASSERT( cert().subject_name() == cert().issuer_name() );
	}
	// sanity check - if dnsname() is_authsigned_ok
	if( dnsname().is_authsigned_ok() ){
		// sanity check - peerid MUST be directly derived from the dnsname
		DBG_ASSERT( peerid() == dnsname().to_string() );
		// sanity check - the cert MUST NOT be selfsigned
		DBG_ASSERT( cert().subject_name() != cert().issuer_name() );
	}
	// sanity check - if dnsname() is_nonesigned_ok
	if( dnsname().is_nonesigned_ok() ){
		// sanity check - peerid MUST be directly derived from router_name_t::host()
		DBG_ASSERT( peerid() == router_peerid_t::from_canonical_string(dnsname().host()) );
		// sanity check - the cert MUST be selfsigned
		DBG_ASSERT( cert().subject_name() == cert().issuer_name() );
	}
	// if all tests passed, it is considered sane, so return true
	return true;
}
Esempio n. 9
0
void SSLSocket::attach() {
    ssl_internal_stack *stack;
    if(idata != 0) {
        stack = (ssl_internal_stack *)idata;
        delete stack;
    }
    stack = new ssl_internal_stack();
    stack->ssl = SSL_new((SSL_CTX *)ctx.getInternal());
    stack->sbio=BIO_new_socket(tsock,BIO_NOCLOSE);
    if(stack->sbio == 0x00)
        throw SSLSocketAddIOFailure();
    SSL_set_bio(stack->ssl, stack->sbio, stack->sbio);
    if(SSL_connect(stack->ssl) <= 0)
        throw SSLConnectFailed();
    //Verify certificate now
    int vres;
    if((vres = SSL_get_verify_result(stack->ssl)) != X509_V_OK) {
#ifdef USE_DEBUG
        ::X509 *x5;
        x5 = SSL_get_peer_certificate(stack->ssl);
        X509 cert(x5);
        X509_free(x5);
#endif
        switch(vres) {
        case X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT:
            throw X509IssuerCertificateNotFound();
        case X509_V_ERR_UNABLE_TO_DECRYPT_CERT_SIGNATURE:
            throw X509UnableToDecryptCertificate();
        case X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT_LOCALLY:
#ifdef USE_DEBUG
            debugmsg(this, "Certificate not found locally.\n");
#endif
            throw CertificateIssuerNotFoundLocally();
        default:
            throw SSLInvalidCertificate();
        }
    }
}
Esempio n. 10
0
void QgsAuthTrustedCAsDialog::showCertInfo( QTreeWidgetItem *item )
{
  if ( !item )
    return;

  QString digest( item->data( 0, Qt::UserRole ).toString() );

  QMap<QString, QPair<QgsAuthCertUtils::CaCertSource, QSslCertificate> > cacertscache(
    QgsApplication::authManager()->caCertsCache() );

  if ( !cacertscache.contains( digest ) )
  {
    QgsDebugMsg( QStringLiteral( "Certificate Authority not in CA certs cache" ) );
    return;
  }

  QSslCertificate cert( cacertscache.value( digest ).second );

  QgsAuthCertInfoDialog *dlg = new QgsAuthCertInfoDialog( cert, false, this );
  dlg->setWindowModality( Qt::WindowModal );
  dlg->resize( 675, 500 );
  dlg->exec();
  dlg->deleteLater();
}
Esempio n. 11
0
SECStatus
AddCertificateFromFile(const char* basePath, const char* filename)
{
  char buf[16384] = { 0 };
  SECStatus rv = ReadFileToBuffer(basePath, filename, buf);
  if (rv != SECSuccess) {
    return rv;
  }
  SECItem certDER;
  rv = CERT_DecodeCertPackage(buf, strlen(buf), DecodeCertCallback, &certDER);
  if (rv != SECSuccess) {
    PrintPRError("CERT_DecodeCertPackage failed");
    return rv;
  }
  ScopedCERTCertificate cert(CERT_NewTempCertificate(CERT_GetDefaultCertDB(),
                                                     &certDER, nullptr, false,
                                                     true));
  PORT_Free(certDER.data);
  if (!cert) {
    PrintPRError("CERT_NewTempCertificate failed");
    return SECFailure;
  }
  ScopedPK11SlotInfo slot(PK11_GetInternalKeySlot());
  if (!slot) {
    PrintPRError("PK11_GetInternalKeySlot failed");
    return SECFailure;
  }
  // The nickname is the filename without '.pem'.
  std::string nickname(filename, strlen(filename) - 4);
  rv = PK11_ImportCert(slot, cert, CK_INVALID_HANDLE, nickname.c_str(), false);
  if (rv != SECSuccess) {
    PrintPRError("PK11_ImportCert failed");
    return rv;
  }
  return SECSuccess;
}
Esempio n. 12
0
void QCACryptoInterface::generateKeyPair(const char* certificateFile, const char *publicKeyFile, const char *privateKeyFile, const char *keyPassword)
{
    if(!QCA::isSupported("pkey") || !QCA::PKey::supportedIOTypes().contains(QCA::PKey::RSA)) {
        qDebug() << "RSA not supported!\n";
        return;
    }

    QCA::PrivateKey secretKey = QCA::KeyGenerator().createRSA(2048);
    if(secretKey.isNull()) {
        qDebug() << "Failed to make private RSA key\n";
        return;
    }

    secretKey.toPEMFile(privateKeyFile, keyPassword);

    // public
    QCA::CertificateOptions opts;
    QCA::Certificate cert(opts, secretKey);

    cert.toPEMFile(certificateFile);

    QCA::PublicKey pubkey = secretKey.toPublicKey();
    pubkey.toPEMFile(publicKeyFile);
}
Esempio n. 13
0
bool QgsAuthPkcs12Edit::validateConfig()
{
  // required components
  QString bundlepath( lePkcs12Bundle->text() );

  bool bundlefound = QFile::exists( bundlepath );

  QgsAuthGuiUtils::fileFound( bundlepath.isEmpty() || bundlefound, lePkcs12Bundle );

  if ( !bundlefound )
  {
    writePkiMessage( lePkcs12Msg, tr( "Missing components" ), Invalid );
    return validityChange( false );
  }

  if ( !QCA::isSupported( "pkcs12" ) )
  {
    writePkiMessage( lePkcs12Msg, tr( "QCA library has no PKCS#12 support" ), Invalid );
    return validityChange( false );
  }

  // load the bundle
  QCA::SecureArray passarray;
  if ( !lePkcs12KeyPass->text().isEmpty() )
    passarray = QCA::SecureArray( lePkcs12KeyPass->text().toUtf8() );

  QCA::ConvertResult res;
  QCA::KeyBundle bundle( QCA::KeyBundle::fromFile( bundlepath, passarray, &res, QString( "qca-ossl" ) ) );

  if ( res == QCA::ErrorFile )
  {
    writePkiMessage( lePkcs12Msg, tr( "Failed to read bundle file" ), Invalid );
    return validityChange( false );
  }
  else if ( res == QCA::ErrorPassphrase )
  {
    writePkiMessage( lePkcs12Msg, tr( "Incorrect bundle password" ), Invalid );
    lePkcs12KeyPass->setPlaceholderText( QString( "Required passphrase" ) );
    return validityChange( false );
  }
  else if ( res == QCA::ErrorDecode )
  {
    writePkiMessage( lePkcs12Msg, tr( "Failed to decode (try entering password)" ), Invalid );
    return validityChange( false );
  }

  if ( bundle.isNull() )
  {
    writePkiMessage( lePkcs12Msg, tr( "Bundle empty or can not be loaded" ), Invalid );
    return validityChange( false );
  }

  // check for primary cert and that it is valid
  QCA::Certificate cert( bundle.certificateChain().primary() );
  if ( cert.isNull() )
  {
    writePkiMessage( lePkcs12Msg, tr( "Bundle client cert can not be loaded" ), Invalid );
    return validityChange( false );
  }

  // TODO: add more robust validation, including cert chain resolution
  QDateTime startdate( cert.notValidBefore() );
  QDateTime enddate( cert.notValidAfter() );
  QDateTime now( QDateTime::currentDateTime() );
  bool bundlevalid = ( now >= startdate && now <= enddate );

  writePkiMessage( lePkcs12Msg,
                   tr( "%1 thru %2" ).arg( startdate.toString() ).arg( enddate.toString() ),
                   ( bundlevalid ? Valid : Invalid ) );

  return validityChange( bundlevalid );
}
nsresult
VerifyCMSDetachedSignatureIncludingCertificate(
  const SECItem& buffer, const SECItem& detachedDigest,
  nsresult (*verifyCertificate)(CERTCertificate* cert, void* context,
                                void* pinArg),
  void *verifyCertificateContext, void* pinArg)
{
  // XXX: missing pinArg is tolerated.
  if (NS_WARN_IF(!buffer.data && buffer.len > 0) ||
      NS_WARN_IF(!detachedDigest.data && detachedDigest.len > 0) ||
      (!verifyCertificate) ||
      NS_WARN_IF(!verifyCertificateContext)) {
    return NS_ERROR_INVALID_ARG;
  }

  ScopedNSSCMSMessage
    cmsMsg(NSS_CMSMessage_CreateFromDER(const_cast<SECItem*>(&buffer), nullptr,
                                        nullptr, nullptr, nullptr, nullptr,
                                        nullptr));
  if (!cmsMsg) {
    return NS_ERROR_CMS_VERIFY_ERROR_PROCESSING;
  }

  if (!NSS_CMSMessage_IsSigned(cmsMsg.get())) {
    return NS_ERROR_CMS_VERIFY_NOT_SIGNED;
  }

  NSSCMSContentInfo* cinfo = NSS_CMSMessage_ContentLevel(cmsMsg.get(), 0);
  if (!cinfo) {
    return NS_ERROR_CMS_VERIFY_NO_CONTENT_INFO;
  }

  // signedData is non-owning
  NSSCMSSignedData* signedData =
    reinterpret_cast<NSSCMSSignedData*>(NSS_CMSContentInfo_GetContent(cinfo));
  if (!signedData) {
    return NS_ERROR_CMS_VERIFY_NO_CONTENT_INFO;
  }

  // Set digest value.
  if (NSS_CMSSignedData_SetDigestValue(signedData, SEC_OID_SHA1,
                                       const_cast<SECItem*>(&detachedDigest))) {
    return NS_ERROR_CMS_VERIFY_BAD_DIGEST;
  }

  // Parse the certificates into CERTCertificate objects held in memory so
  // verifyCertificate will be able to find them during path building.
  ScopedCERTCertList certs(CERT_NewCertList());
  if (!certs) {
    return NS_ERROR_OUT_OF_MEMORY;
  }
  if (signedData->rawCerts) {
    for (size_t i = 0; signedData->rawCerts[i]; ++i) {
      ScopedCERTCertificate
        cert(CERT_NewTempCertificate(CERT_GetDefaultCertDB(),
                                     signedData->rawCerts[i], nullptr, false,
                                     true));
      // Skip certificates that fail to parse
      if (cert) {
        if (CERT_AddCertToListTail(certs.get(), cert.get()) == SECSuccess) {
          cert.forget(); // ownership transfered
        } else {
          return NS_ERROR_OUT_OF_MEMORY;
        }
      }
    }
  }

  // Get the end-entity certificate.
  int numSigners = NSS_CMSSignedData_SignerInfoCount(signedData);
  if (NS_WARN_IF(numSigners != 1)) {
    return NS_ERROR_CMS_VERIFY_ERROR_PROCESSING;
  }
  // signer is non-owning.
  NSSCMSSignerInfo* signer = NSS_CMSSignedData_GetSignerInfo(signedData, 0);
  if (NS_WARN_IF(!signer)) {
    return NS_ERROR_CMS_VERIFY_ERROR_PROCESSING;
  }
  CERTCertificate* signerCert =
    NSS_CMSSignerInfo_GetSigningCertificate(signer, CERT_GetDefaultCertDB());
  if (!signerCert) {
    return NS_ERROR_CMS_VERIFY_ERROR_PROCESSING;
  }

  nsresult rv = verifyCertificate(signerCert, verifyCertificateContext, pinArg);
  if (NS_WARN_IF(NS_FAILED(rv))) {
    return rv;
  }

  // See NSS_CMSContentInfo_GetContentTypeOID, which isn't exported from NSS.
  SECOidData* contentTypeOidData =
    SECOID_FindOID(&signedData->contentInfo.contentType);
  if (!contentTypeOidData) {
    return NS_ERROR_CMS_VERIFY_ERROR_PROCESSING;
  }

  return MapSECStatus(NSS_CMSSignerInfo_Verify(signer,
                         const_cast<SECItem*>(&detachedDigest),
                         &contentTypeOidData->oid));
}
Esempio n. 15
0
KdeConnectConfig::KdeConnectConfig()
    : d(new KdeConnectConfigPrivate)
{
    //qCDebug(KDECONNECT_CORE) << "QCA supported capabilities:" << QCA::supportedFeatures().join(",");
    if(!QCA::isSupported("rsa")) {
        qCritical() << "Could not find support for RSA in your QCA installation";
        Daemon::instance()->reportError(
            i18n("KDE Connect failed to start"),
            i18n("Could not find support for RSA in your QCA installation. If your "
                 "distribution provides separate packages for QCA-ossl and QCA-gnupg, "
                 "make sure you have them installed and try again."));
        return;
    }

    //Make sure base directory exists
    QDir().mkpath(baseConfigDir().path());

    //.config/kdeconnect/config
    d->config = new QSettings(baseConfigDir().absoluteFilePath(QStringLiteral("config")), QSettings::IniFormat);
    d->trusted_devices = new QSettings(baseConfigDir().absoluteFilePath(QStringLiteral("trusted_devices")), QSettings::IniFormat);

    //Register my own id if not there yet
    if (!d->config->contains(QStringLiteral("id"))) {
        QString uuid = QUuid::createUuid().toString();
        DbusHelper::filterNonExportableCharacters(uuid);
        d->config->setValue(QStringLiteral("id"), uuid);
        d->config->sync();
        qCDebug(KDECONNECT_CORE) << "My id:" << uuid;
    }

    const QFile::Permissions strict = QFile::ReadOwner | QFile::WriteOwner | QFile::ReadUser | QFile::WriteUser;

    QString keyPath = privateKeyPath();
    QFile privKey(keyPath);
    if (privKey.exists() && privKey.open(QIODevice::ReadOnly)) {

        d->privateKey = QCA::PrivateKey::fromPEM(privKey.readAll());

    } else {

        d->privateKey = QCA::KeyGenerator().createRSA(2048);

        if (!privKey.open(QIODevice::ReadWrite | QIODevice::Truncate))  {
            Daemon::instance()->reportError(QStringLiteral("KDE Connect"), i18n("Could not store private key file: %1", keyPath));
        } else {
            privKey.setPermissions(strict);
            privKey.write(d->privateKey.toPEM().toLatin1());
        }
    }

    QString certPath = certificatePath();
    QFile cert(certPath);
    if (cert.exists() && cert.open(QIODevice::ReadOnly)) {

        d->certificate = QSslCertificate::fromPath(certPath).at(0);

    } else {

        // FIXME: We only use QCA here to generate the cert and key, would be nice to get rid of it completely.
        // The same thing we are doing with QCA could be done invoking openssl (altought it's potentially less portable):
        // openssl req -new -x509 -sha256 -newkey rsa:2048 -nodes -keyout privateKey.pem -days 3650 -out certificate.pem -subj "/O=KDE/OU=KDE Connect/CN=_e6e29ad4_2b31_4b6d_8f7a_9872dbaa9095_"

        QCA::CertificateOptions certificateOptions = QCA::CertificateOptions();
        QDateTime startTime = QDateTime::currentDateTime().addYears(-1);
        QDateTime endTime = startTime.addYears(10);
        QCA::CertificateInfo certificateInfo;
        certificateInfo.insert(QCA::CommonName,deviceId());
        certificateInfo.insert(QCA::Organization,QStringLiteral("KDE"));
        certificateInfo.insert(QCA::OrganizationalUnit,QStringLiteral("Kde connect"));
        certificateOptions.setInfo(certificateInfo);
        certificateOptions.setFormat(QCA::PKCS10);
        certificateOptions.setSerialNumber(QCA::BigInteger(10));
        certificateOptions.setValidityPeriod(startTime, endTime);

        d->certificate = QSslCertificate(QCA::Certificate(certificateOptions, d->privateKey).toPEM().toLatin1());

        if (!cert.open(QIODevice::ReadWrite | QIODevice::Truncate))  {
            Daemon::instance()->reportError(QStringLiteral("KDE Connect"), i18n("Could not store certificate file: %1", certPath));
        } else {
            cert.setPermissions(strict);
            cert.write(d->certificate.toPem());
        }
    }

    //Extra security check
    if (QFile::permissions(keyPath) != strict) {
        qCWarning(KDECONNECT_CORE) << "Warning: KDE Connect private key file has too open permissions " << keyPath;
    }
}
Esempio n. 16
0
	void WebSocketQt::setupSocketWithSSLDataSource(SSLDataSource * dataSource)
	{
		QSslConfiguration config;

		QFile localFile(WebSocketQt::toString(dataSource->clientLocalCertificateFilePath()));
		if (localFile.open(QIODevice::ReadOnly))
		{
			QSslCertificate cert(localFile.readAll());
			localFile.close();
			if (cert.isNull())
			{
#ifdef FAYECPP_DEBUG_MESSAGES
				qDebug() << "SocketQT: LocalCertificate is NULL";
#endif
			}
			else
			{
				config.setLocalCertificate(cert);
			}
		}

		QFile keyFile(WebSocketQt::toString(dataSource->clientPrivateKeyFilePath()));
		if (keyFile.open(QIODevice::ReadOnly))
		{
			QByteArray pp;
			pp.append(WebSocketQt::toString(dataSource->clientPrivateKeyPassPhrase()));
			QSslKey key(keyFile.readAll(),
						QSsl::Rsa,
						QSsl::Pem,
						QSsl::PrivateKey,
						pp);
			pp.clear();
			keyFile.close();
			if (key.isNull())
			{
#ifdef FAYECPP_DEBUG_MESSAGES
				qDebug() << "SocketQT: PrivateKey is NULL";
#endif
			}
			else
			{
				config.setPrivateKey(key);
			}
		}

		QFile caFile(WebSocketQt::toString(dataSource->clientCACertificateFilePath()));
		if (caFile.open(QIODevice::ReadOnly))
		{
			QSslCertificate cert(caFile.readAll());
			caFile.close();
			if (cert.isNull())
			{
#ifdef FAYECPP_DEBUG_MESSAGES
				qDebug() << "SocketQT: CACertificate is NULL";
#endif
			}
			else
			{
				QList<QSslCertificate> caList(config.caCertificates());
				caList.append(cert);
				config.setCaCertificates(caList);
			}
		}

		_socket->setSslConfiguration(config);
	}
Esempio n. 17
0
Core::Core()
    : QObject(),
      _storage(0)
{
#ifdef HAVE_UMASK
    umask(S_IRWXG | S_IRWXO);
#endif
    _startTime = QDateTime::currentDateTime().toUTC(); // for uptime :)

    Quassel::loadTranslation(QLocale::system());

    // FIXME: MIGRATION 0.3 -> 0.4: Move database and core config to new location
    // Move settings, note this does not delete the old files
#ifdef Q_WS_MAC
    QSettings newSettings("quassel-irc.org", "quasselcore");
#else

# ifdef Q_WS_WIN
    QSettings::Format format = QSettings::IniFormat;
# else
    QSettings::Format format = QSettings::NativeFormat;
# endif
    QString newFilePath = Quassel::configDirPath() + "quasselcore"
                          + ((format == QSettings::NativeFormat) ? QLatin1String(".conf") : QLatin1String(".ini"));
    QSettings newSettings(newFilePath, format);
#endif /* Q_WS_MAC */

    if (newSettings.value("Config/Version").toUInt() == 0) {
#   ifdef Q_WS_MAC
        QString org = "quassel-irc.org";
#   else
        QString org = "Quassel Project";
#   endif
        QSettings oldSettings(org, "Quassel Core");
        if (oldSettings.allKeys().count()) {
            qWarning() << "\n\n*** IMPORTANT: Config and data file locations have changed. Attempting to auto-migrate your core settings...";
            foreach(QString key, oldSettings.allKeys())
            newSettings.setValue(key, oldSettings.value(key));
            newSettings.setValue("Config/Version", 1);
            qWarning() << "*   Your core settings have been migrated to" << newSettings.fileName();

#ifndef Q_WS_MAC /* we don't need to move the db and cert for mac */
#ifdef Q_OS_WIN32
            QString quasselDir = qgetenv("APPDATA") + "/quassel/";
#elif defined Q_WS_MAC
            QString quasselDir = QDir::homePath() + "/Library/Application Support/Quassel/";
#else
            QString quasselDir = QDir::homePath() + "/.quassel/";
#endif

            QFileInfo info(Quassel::configDirPath() + "quassel-storage.sqlite");
            if (!info.exists()) {
                // move database, if we found it
                QFile oldDb(quasselDir + "quassel-storage.sqlite");
                if (oldDb.exists()) {
                    bool success = oldDb.rename(Quassel::configDirPath() + "quassel-storage.sqlite");
                    if (success)
                        qWarning() << "*   Your database has been moved to" << Quassel::configDirPath() + "quassel-storage.sqlite";
                    else
                        qWarning() << "!!! Moving your database has failed. Please move it manually into" << Quassel::configDirPath();
                }
            }
            // move certificate
            QFileInfo certInfo(quasselDir + "quasselCert.pem");
            if (certInfo.exists()) {
                QFile cert(quasselDir + "quasselCert.pem");
                bool success = cert.rename(Quassel::configDirPath() + "quasselCert.pem");
                if (success)
                    qWarning() << "*   Your certificate has been moved to" << Quassel::configDirPath() + "quasselCert.pem";
                else
                    qWarning() << "!!! Moving your certificate has failed. Please move it manually into" << Quassel::configDirPath();
            }
#endif /* !Q_WS_MAC */
            qWarning() << "*** Migration completed.\n\n";
        }
    }
    // MIGRATION end

    // check settings version
    // so far, we only have 1
    CoreSettings s;
    if (s.version() != 1) {
        qCritical() << "Invalid core settings version, terminating!";
        exit(EXIT_FAILURE);
    }

    registerStorageBackends();

    connect(&_storageSyncTimer, SIGNAL(timeout()), this, SLOT(syncStorage()));
    _storageSyncTimer.start(10 * 60 * 1000); // 10 minutes
}
Esempio n. 18
0
int
main(int argc, char* argv[])
{
  ScopedXPCOM xpcom("TestCertDB");
  if (xpcom.failed()) {
    fail("couldn't initialize XPCOM");
    return 1;
  }
  {
    nsCOMPtr<nsIPrefBranch> prefs(do_GetService(NS_PREFSERVICE_CONTRACTID));
    if (!prefs) {
      fail("couldn't get nsIPrefBranch");
      return 1;
    }
    // When PSM initializes, it attempts to get some localized strings.
    // As a result, Android flips out if this isn't set.
    nsresult rv = prefs->SetBoolPref("intl.locale.matchOS", true);
    if (NS_FAILED(rv)) {
      fail("couldn't set pref 'intl.locale.matchOS'");
      return 1;
    }
    nsCOMPtr<nsIX509CertDB> certdb(do_GetService(NS_X509CERTDB_CONTRACTID));
    if (!certdb) {
      fail("couldn't get certdb");
      return 1;
    }
    nsCOMPtr<nsIX509CertList> certList;
    rv = certdb->GetCerts(getter_AddRefs(certList));
    if (NS_FAILED(rv)) {
      fail("couldn't get list of certificates");
      return 1;
    }
    nsCOMPtr<nsISimpleEnumerator> enumerator;
    rv = certList->GetEnumerator(getter_AddRefs(enumerator));
    if (NS_FAILED(rv)) {
      fail("couldn't enumerate certificate list");
      return 1;
    }
    bool foundBuiltIn = false;
    bool hasMore = false;
    while (NS_SUCCEEDED(enumerator->HasMoreElements(&hasMore)) && hasMore) {
      nsCOMPtr<nsISupports> supports;
      if (NS_FAILED(enumerator->GetNext(getter_AddRefs(supports)))) {
        fail("couldn't get next certificate");
        return 1;
      }
      nsCOMPtr<nsIX509Cert> cert(do_QueryInterface(supports));
      if (!cert) {
        fail("couldn't QI to nsIX509Cert");
        return 1;
      }
      if (NS_FAILED(cert->GetIsBuiltInRoot(&foundBuiltIn))) {
        fail("GetIsBuiltInRoot failed");
        return 1;
      }
      if (foundBuiltIn) {
        break;
      }
    }
    if (foundBuiltIn) {
      passed("successfully loaded at least one built-in certificate");
    } else {
      fail("didn't load any built-in certificates");
      return 1;
    }
  } // this scopes the nsCOMPtrs
  // no nsCOMPtrs are allowed to be alive when you call NS_ShutdownXPCOM
  return 0;
}
Esempio n. 19
0
int main(int argc, char* argv[])
{
  try
  {
    log_init();

    cxxtools::Arg<std::string> ip(argc, argv, 'i');
    cxxtools::Arg<unsigned short> port(argc, argv, 'p', 1234);
    cxxtools::Arg<unsigned> bufsize(argc, argv, 'b', 8192);
    cxxtools::Arg<bool> listen(argc, argv, 'l');
    cxxtools::Arg<bool> read_reply(argc, argv, 'r');
    cxxtools::Arg<bool> ssl(argc, argv, 's');
    cxxtools::Arg<std::string> cert(argc, argv, "--cert");
    cxxtools::Arg<std::string> ca(argc, argv, "--CA");

    if (listen)
    {
      // I'm a server

      // listen to a port
      cxxtools::net::TcpServer server(ip.getValue(), port);

      // accept a connetion
      cxxtools::net::TcpStream worker(server, bufsize);

      if (ssl)
      {
          if (cert.isSet())
              worker.loadSslCertificateFile(cert);
          if (ca.isSet())
              worker.setSslVerify(2, ca);
          worker.sslAccept();
      }

      // copy to stdout
      std::cout << worker.rdbuf();
    }
    else
    {
      // I'm a client

      // connect to server
      cxxtools::net::TcpStream peer(ip, port, bufsize);

      if (ssl)
      {
          if (cert.isSet())
              peer.loadSslCertificateFile(cert);
          peer.sslConnect();
      }

      if (argc > 1)
      {
          for (int a = 1; a < argc; ++a)
          {
              std::ifstream in(argv[a]);
              peer << in.rdbuf() << std::flush;
          }
      }
      else
      {
          // copy stdin to server
          peer << std::cin.rdbuf() << std::flush;
      }

      if (read_reply)
        // copy answer to stdout
        std::cout << peer.rdbuf() << std::flush;
    }
  }
  catch (const std::exception& e)
  {
    std::cerr << e.what() << std::endl;
  }
}
Esempio n. 20
0
// Validate the peer's certificate list, from root to peer (last to first)
int CertManager::Validate()
{
    CertList::reverse_iterator last = peerList_.rbegin();
    size_t count = peerList_.size();

    while ( count > 1 ) {
        TaoCrypt::Source source((*last)->get_buffer(), (*last)->get_length());
        TaoCrypt::CertDecoder cert(source, true, &signers_, verifyNone_);

        if (int err = cert.GetError().What())
            return err;

        const TaoCrypt::PublicKey& key = cert.GetPublicKey();
        signers_.push_back(NEW_YS TaoCrypt::Signer(key.GetKey(), key.size(),
                                        cert.GetCommonName(), cert.GetHash()));
        ++last;
        --count;
    }

    if (count) {
        // peer's is at the front
        TaoCrypt::Source source((*last)->get_buffer(), (*last)->get_length());
        TaoCrypt::CertDecoder cert(source, true, &signers_, verifyNone_);

        int err = cert.GetError().What();
        if ( err && err != TaoCrypt::SIG_OTHER_E)
            return err;

        uint sz = cert.GetPublicKey().size();
        peerPublicKey_.allocate(sz);
        peerPublicKey_.assign(cert.GetPublicKey().GetKey(), sz);

        if (cert.GetKeyType() == TaoCrypt::RSAk)
            peerKeyType_ = rsa_sa_algo;
        else
            peerKeyType_ = dsa_sa_algo;

        size_t iSz = strlen(cert.GetIssuer()) + 1;
        size_t sSz = strlen(cert.GetCommonName()) + 1;
        ASN1_STRING beforeDate, afterDate;
        beforeDate.data= (unsigned char *) cert.GetBeforeDate();
        beforeDate.type= cert.GetBeforeDateType();
        beforeDate.length= strlen((char *) beforeDate.data) + 1;
        afterDate.data= (unsigned char *) cert.GetAfterDate();
        afterDate.type= cert.GetAfterDateType();
        afterDate.length= strlen((char *) afterDate.data) + 1;
        peerX509_ = NEW_YS X509(cert.GetIssuer(), iSz, cert.GetCommonName(),
                                sSz, &beforeDate, &afterDate);

        if (err == TaoCrypt::SIG_OTHER_E && verifyCallback_) {
            X509_STORE_CTX store;
            store.error = err;
            store.error_depth = static_cast<int>(count) - 1;
            store.current_cert = peerX509_;

            int ok = verifyCallback_(0, &store);
            if (ok) return 0;
        }

        if (err == TaoCrypt::SIG_OTHER_E) return err;
    }
    return 0;
}
bool verify_X509_cert_chain(const std::vector<std::string> &certChain, const std::string &hostName)
{
    JNIEnv* env = get_jvm_env();

    // Possible performance improvement:
    // In the future we could gain performance by turning all the jclass local
    // references into global references. Then we could lazy initialize and
    // save them globally. If this is done I'm not exactly sure where the release
    // should be.

    // ByteArrayInputStream
    java_local_ref<jclass> byteArrayInputStreamClass(env->FindClass("java/io/ByteArrayInputStream"));
    CHECK_JREF(env, byteArrayInputStreamClass);
    jmethodID byteArrayInputStreamConstructorMethod = env->GetMethodID(
        byteArrayInputStreamClass.get(),
        "<init>",
        "([B)V");
    CHECK_JMID(env, byteArrayInputStreamConstructorMethod);

    // CertificateFactory
    java_local_ref<jclass> certificateFactoryClass(env->FindClass("java/security/cert/CertificateFactory"));
    CHECK_JREF(env, certificateFactoryClass);
    jmethodID certificateFactoryGetInstanceMethod = env->GetStaticMethodID(
        certificateFactoryClass.get(),
        "getInstance",
        "(Ljava/lang/String;)Ljava/security/cert/CertificateFactory;");
    CHECK_JMID(env, certificateFactoryGetInstanceMethod);
    jmethodID generateCertificateMethod = env->GetMethodID(
        certificateFactoryClass.get(),
        "generateCertificate",
        "(Ljava/io/InputStream;)Ljava/security/cert/Certificate;");
    CHECK_JMID(env, generateCertificateMethod);

    // X509Certificate
    java_local_ref<jclass> X509CertificateClass(env->FindClass("java/security/cert/X509Certificate"));
    CHECK_JREF(env, X509CertificateClass);

    // TrustManagerFactory
    java_local_ref<jclass> trustManagerFactoryClass(env->FindClass("javax/net/ssl/TrustManagerFactory"));
    CHECK_JREF(env, trustManagerFactoryClass);
    jmethodID trustManagerFactoryGetInstanceMethod = env->GetStaticMethodID(
        trustManagerFactoryClass.get(),
        "getInstance",
        "(Ljava/lang/String;)Ljavax/net/ssl/TrustManagerFactory;");
    CHECK_JMID(env, trustManagerFactoryGetInstanceMethod);
    jmethodID trustManagerFactoryInitMethod = env->GetMethodID(
        trustManagerFactoryClass.get(),
        "init",
        "(Ljava/security/KeyStore;)V");
    CHECK_JMID(env, trustManagerFactoryInitMethod);
    jmethodID trustManagerFactoryGetTrustManagersMethod = env->GetMethodID(
        trustManagerFactoryClass.get(),
        "getTrustManagers",
        "()[Ljavax/net/ssl/TrustManager;");
    CHECK_JMID(env, trustManagerFactoryGetTrustManagersMethod);

    // X509TrustManager
    java_local_ref<jclass> X509TrustManagerClass(env->FindClass("javax/net/ssl/X509TrustManager"));
    CHECK_JREF(env, X509TrustManagerClass);
    jmethodID X509TrustManagerCheckServerTrustedMethod = env->GetMethodID(
        X509TrustManagerClass.get(),
        "checkServerTrusted",
        "([Ljava/security/cert/X509Certificate;Ljava/lang/String;)V");
    CHECK_JMID(env, X509TrustManagerCheckServerTrustedMethod);

    // StrictHostnameVerifier
    java_local_ref<jclass> strictHostnameVerifierClass(env->FindClass("org/apache/http/conn/ssl/StrictHostnameVerifier"));
    CHECK_JREF(env, strictHostnameVerifierClass);
    jmethodID strictHostnameVerifierConstructorMethod = env->GetMethodID(strictHostnameVerifierClass.get(), "<init>", "()V");
    CHECK_JMID(env, strictHostnameVerifierConstructorMethod);
    jmethodID strictHostnameVerifierVerifyMethod = env->GetMethodID(
        strictHostnameVerifierClass.get(),
        "verify",
        "(Ljava/lang/String;Ljava/security/cert/X509Certificate;)V");
    CHECK_JMID(env, strictHostnameVerifierVerifyMethod);

    // Create CertificateFactory
    java_local_ref<jstring> XDot509String(env->NewStringUTF("X.509"));
    CHECK_JREF(env, XDot509String);
    java_local_ref<jobject> certificateFactory(env->CallStaticObjectMethod(
         certificateFactoryClass.get(),
         certificateFactoryGetInstanceMethod,
         XDot509String.get()));
    CHECK_JREF(env, certificateFactory);

    // Create Java array to store all the certs in.
    java_local_ref<jobjectArray> certsArray(env->NewObjectArray(certChain.size(), X509CertificateClass.get(), nullptr));
    CHECK_JREF(env, certsArray);

    // For each certificate perform the following steps:
    //   1. Create ByteArrayInputStream backed by DER certificate bytes
    //   2. Create Certificate using CertificateFactory.generateCertificate
    //   3. Add Certificate to array
    int i = 0;
    for(const auto &certData : certChain)
    {
        java_local_ref<jbyteArray> byteArray(env->NewByteArray(certData.size()));
        CHECK_JREF(env, byteArray);
        env->SetByteArrayRegion(byteArray.get(), 0, certData.size(), reinterpret_cast<const jbyte *>(certData.c_str()));
        CHECK_JNI(env);
        java_local_ref<jobject> byteArrayInputStream(env->NewObject(
            byteArrayInputStreamClass.get(),
            byteArrayInputStreamConstructorMethod,
            byteArray.get()));
        CHECK_JREF(env, byteArrayInputStream);

        java_local_ref<jobject> cert(env->CallObjectMethod(
            certificateFactory.get(),
            generateCertificateMethod,
            byteArrayInputStream.get()));
        CHECK_JREF(env, cert);

        env->SetObjectArrayElement(certsArray.get(), i, cert.get());
        CHECK_JNI(env);
        ++i;
    }

    // Create TrustManagerFactory, init with Android system certs
    java_local_ref<jstring> X509String(env->NewStringUTF("X509"));
    CHECK_JREF(env, X509String);
    java_local_ref<jobject> trustFactoryManager(env->CallStaticObjectMethod(
        trustManagerFactoryClass.get(),
        trustManagerFactoryGetInstanceMethod,
        X509String.get()));
    CHECK_JREF(env, trustFactoryManager);
    env->CallVoidMethod(trustFactoryManager.get(), trustManagerFactoryInitMethod, nullptr);
    CHECK_JNI(env);

    // Get TrustManager
    java_local_ref<jobjectArray> trustManagerArray(static_cast<jobjectArray>(
        env->CallObjectMethod(trustFactoryManager.get(), trustManagerFactoryGetTrustManagersMethod)));
    CHECK_JREF(env, trustManagerArray);
    java_local_ref<jobject> trustManager(env->GetObjectArrayElement(trustManagerArray.get(), 0));
    CHECK_JREF(env, trustManager);

    // Validate certificate chain.
    java_local_ref<jstring> RSAString(env->NewStringUTF("RSA"));
    CHECK_JREF(env, RSAString);
    env->CallVoidMethod(
        trustManager.get(),
        X509TrustManagerCheckServerTrustedMethod,
        certsArray.get(),
        RSAString.get());
    CHECK_JNI(env);

    // Verify hostname on certificate according to RFC 2818.
    java_local_ref<jobject> hostnameVerifier(env->NewObject(
        strictHostnameVerifierClass.get(), strictHostnameVerifierConstructorMethod));
    CHECK_JREF(env, hostnameVerifier);
    java_local_ref<jstring> hostNameString(env->NewStringUTF(hostName.c_str()));
    CHECK_JREF(env, hostNameString);
    java_local_ref<jobject> cert(env->GetObjectArrayElement(certsArray.get(), 0));
    CHECK_JREF(env, cert);
    env->CallVoidMethod(
        hostnameVerifier.get(),
        strictHostnameVerifierVerifyMethod,
        hostNameString.get(),
        cert.get());
    CHECK_JNI(env);

    return true;
}
Esempio n. 22
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.
  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;
}
Esempio n. 23
0
bool SSLSocket::enableCrypto(bool activate /* = true */) {
  if (activate && !m_ssl_active) {
    double timeout = m_connect_timeout;
    bool blocked = m_is_blocked;
    if (!m_state_set) {
      if (m_client) {
        SSL_set_connect_state(m_handle);
      } else {
        SSL_set_accept_state(m_handle);
      }
      m_state_set = true;
    }

    if (m_client && setBlocking(false)) {
      m_is_blocked = false;
    }

    int n;
    bool retry = true;
    do {
      if (m_client) {
        struct timeval tvs, tve;
        struct timezone tz;

        gettimeofday(&tvs, &tz);
        n = SSL_connect(m_handle);
        gettimeofday(&tve, &tz);

        timeout -= (tve.tv_sec + (double) tve.tv_usec / 1000000) -
          (tvs.tv_sec + (double) tvs.tv_usec / 1000000);
        if (timeout < 0) {
          raise_warning("SSL: connection timeout");
          return -1;
        }
      } else {
        n = SSL_accept(m_handle);
      }

      if (n <= 0) {
        retry = handleError(n, true);
      } else {
        break;
      }
    } while (retry);

    if (m_client && m_is_blocked != blocked && setBlocking(blocked)) {
      m_is_blocked = blocked;
    }

    if (n == 1) {
      X509 *peer_cert = SSL_get_peer_certificate(m_handle);
      if (!applyVerificationPolicy(peer_cert)) {
        SSL_shutdown(m_handle);
      } else {
        m_ssl_active = true;

        /* allow the script to capture the peer cert
         * and/or the certificate chain */
        if (m_context["capture_peer_cert"].toBoolean()) {
          Object cert(new Certificate(peer_cert));
          m_context.set("peer_certificate", cert);
          peer_cert = nullptr;
        }

        if (m_context["capture_peer_cert_chain"].toBoolean()) {
          Array arr;
          STACK_OF(X509) *chain = SSL_get_peer_cert_chain(m_handle);
          if (chain) {
            for (int i = 0; i < sk_X509_num(chain); i++) {
              X509 *mycert = X509_dup(sk_X509_value(chain, i));
              arr.append(Object(new Certificate(mycert)));
            }
          }
          m_context.set("peer_certificate_chain", arr);
        }
      }

      if (peer_cert) {
        X509_free(peer_cert);
      }
    } else  {
      n = errno == EAGAIN ? 0 : -1;
    }

    return n >= 0;

  } else if (!activate && m_ssl_active) {
    /* deactivate - common for server/client */
    SSL_shutdown(m_handle);
    m_ssl_active = false;
  }
  return true;
}
OSStatus SecIdentityCopyPreference(
    CFStringRef name,
    CSSM_KEYUSE keyUsage,
    CFArrayRef validIssuers,
    SecIdentityRef *identity)
{
    // The original implementation of SecIdentityCopyPreference matches the exact string only.
    // That implementation has been moved to _SecIdentityCopyPreferenceMatchingName (above),
    // and this function is a wrapper which calls it, so that existing clients will get the
    // extended behavior of server domain matching for items that specify URLs.
    // (Note that behavior is unchanged if the specified name is not a URL.)

    BEGIN_SECAPI

    CFTypeRef val = (CFTypeRef)CFPreferencesCopyValue(CFSTR("LogIdentityPreferenceLookup"),
                    CFSTR("com.apple.security"),
                    kCFPreferencesCurrentUser,
                    kCFPreferencesAnyHost);
    Boolean logging = false;
    if (val && CFGetTypeID(val) == CFBooleanGetTypeID()) {
        logging = CFBooleanGetValue((CFBooleanRef)val);
        CFRelease(val);
    }

    OSStatus status = errSecItemNotFound;
    CFArrayRef names = _SecIdentityCopyPossiblePaths(name);
    if (!names) {
        return status;
    }

    CFIndex idx, total = CFArrayGetCount(names);
    for (idx = 0; idx < total; idx++) {
        CFStringRef aName = (CFStringRef)CFArrayGetValueAtIndex(names, idx);
        try {
            status = _SecIdentityCopyPreferenceMatchingName(aName, keyUsage, validIssuers, identity);
        }
        catch (...) { status = errSecItemNotFound; }

        if (logging) {
            // get identity label
            CFStringRef labelString = NULL;
            if (!status && identity && *identity) {
                try {
                    SecPointer<Certificate> cert(Identity::required(*identity)->certificate());
                    cert->inferLabel(false, &labelString);
                }
                catch (...) { labelString = NULL; };
            }
            char *labelBuf = NULL;
            CFIndex labelBufSize = (labelString) ? CFStringGetLength(labelString) * 4 : 4;
            labelBuf = (char *)malloc(labelBufSize);
            if (!labelString || !CFStringGetCString(labelString, labelBuf, labelBufSize, kCFStringEncodingUTF8)) {
                labelBuf[0] = 0;
            }
            if (labelString) {
                CFRelease(labelString);
            }

            // get service name
            char *serviceBuf = NULL;
            CFIndex serviceBufSize = CFStringGetLength(aName) * 4;
            serviceBuf = (char *)malloc(serviceBufSize);
            if (!CFStringGetCString(aName, serviceBuf, serviceBufSize, kCFStringEncodingUTF8)) {
                serviceBuf[0] = 0;
            }

            syslog(LOG_NOTICE, "preferred identity: \"%s\" found for \"%s\"\n", labelBuf, serviceBuf);
            if (!status && name) {
                char *nameBuf = NULL;
                CFIndex nameBufSize = CFStringGetLength(name) * 4;
                nameBuf = (char *)malloc(nameBufSize);
                if (!CFStringGetCString(name, nameBuf, nameBufSize, kCFStringEncodingUTF8)) {
                    nameBuf[0] = 0;
                }
                syslog(LOG_NOTICE, "lookup complete; will use: \"%s\" for \"%s\"\n", labelBuf, nameBuf);
                free(nameBuf);
            }

            free(labelBuf);
            free(serviceBuf);
        }

        if (status == errSecSuccess) {
            break; // match found
        }
    }

    CFRelease(names);
    return status;

    END_SECAPI
}
Esempio n. 25
0
  nsresult Generate()
  {
    nsresult rv;

    // Get the key slot for generation later
    UniquePK11SlotInfo slot(PK11_GetInternalKeySlot());
    if (!slot) {
      return mozilla::psm::GetXPCOMFromNSSError(PR_GetError());
    }

    // Remove existing certs with this name (if any)
    rv = RemoveExisting();
    if (NS_FAILED(rv)) {
      return rv;
    }

    // Generate a new cert
    NS_NAMED_LITERAL_CSTRING(commonNamePrefix, "CN=");
    nsAutoCString subjectNameStr(commonNamePrefix + mNickname);
    UniqueCERTName subjectName(CERT_AsciiToName(subjectNameStr.get()));
    if (!subjectName) {
      return mozilla::psm::GetXPCOMFromNSSError(PR_GetError());
    }

    // Use the well-known NIST P-256 curve
    SECOidData* curveOidData = SECOID_FindOIDByTag(SEC_OID_SECG_EC_SECP256R1);
    if (!curveOidData) {
      return mozilla::psm::GetXPCOMFromNSSError(PR_GetError());
    }

    // Get key params from the curve
    ScopedAutoSECItem keyParams(2 + curveOidData->oid.len);
    keyParams.data[0] = SEC_ASN1_OBJECT_ID;
    keyParams.data[1] = curveOidData->oid.len;
    memcpy(keyParams.data + 2, curveOidData->oid.data, curveOidData->oid.len);

    // Generate cert key pair
    SECKEYPublicKey* tempPublicKey;
    UniqueSECKEYPrivateKey privateKey(
      PK11_GenerateKeyPair(slot.get(), CKM_EC_KEY_PAIR_GEN, &keyParams,
                           &tempPublicKey, true /* token */,
                           true /* sensitive */, nullptr));
    UniqueSECKEYPublicKey publicKey(tempPublicKey);
    tempPublicKey = nullptr;
    if (!privateKey || !publicKey) {
      return mozilla::psm::GetXPCOMFromNSSError(PR_GetError());
    }

    // Create subject public key info and cert request
    UniqueCERTSubjectPublicKeyInfo spki(
      SECKEY_CreateSubjectPublicKeyInfo(publicKey.get()));
    if (!spki) {
      return mozilla::psm::GetXPCOMFromNSSError(PR_GetError());
    }
    UniqueCERTCertificateRequest certRequest(
      CERT_CreateCertificateRequest(subjectName.get(), spki.get(), nullptr));
    if (!certRequest) {
      return mozilla::psm::GetXPCOMFromNSSError(PR_GetError());
    }

    // Valid from one day before to 1 year after
    static const PRTime oneDay = PRTime(PR_USEC_PER_SEC)
                               * PRTime(60)  // sec
                               * PRTime(60)  // min
                               * PRTime(24); // hours

    PRTime now = PR_Now();
    PRTime notBefore = now - oneDay;
    PRTime notAfter = now + (PRTime(365) * oneDay);
    UniqueCERTValidity validity(CERT_CreateValidity(notBefore, notAfter));
    if (!validity) {
      return mozilla::psm::GetXPCOMFromNSSError(PR_GetError());
    }

    // Generate random serial
    unsigned long serial;
    // This serial in principle could collide, but it's unlikely
    rv = MapSECStatus(PK11_GenerateRandomOnSlot(
           slot.get(), BitwiseCast<unsigned char*, unsigned long*>(&serial),
           sizeof(serial)));
    if (NS_FAILED(rv)) {
      return rv;
    }

    // Create the cert from these pieces
    UniqueCERTCertificate cert(
      CERT_CreateCertificate(serial, subjectName.get(), validity.get(),
                             certRequest.get()));
    if (!cert) {
      return mozilla::psm::GetXPCOMFromNSSError(PR_GetError());
    }

    // Update the cert version to X509v3
    if (!cert->version.data) {
      return NS_ERROR_INVALID_POINTER;
    }
    *(cert->version.data) = SEC_CERTIFICATE_VERSION_3;
    cert->version.len = 1;

    // Set cert signature algorithm
    PLArenaPool* arena = cert->arena;
    if (!arena) {
      return NS_ERROR_INVALID_POINTER;
    }
    rv = MapSECStatus(
           SECOID_SetAlgorithmID(arena, &cert->signature,
                                 SEC_OID_ANSIX962_ECDSA_SHA256_SIGNATURE, 0));
    if (NS_FAILED(rv)) {
      return rv;
    }

    // Encode and self-sign the cert
    UniqueSECItem certDER(
      SEC_ASN1EncodeItem(nullptr, nullptr, cert.get(),
                         SEC_ASN1_GET(CERT_CertificateTemplate)));
    if (!certDER) {
      return mozilla::psm::GetXPCOMFromNSSError(PR_GetError());
    }
    rv = MapSECStatus(
           SEC_DerSignData(arena, &cert->derCert, certDER->data, certDER->len,
                           privateKey.get(),
                           SEC_OID_ANSIX962_ECDSA_SHA256_SIGNATURE));
    if (NS_FAILED(rv)) {
      return rv;
    }

    // Create a CERTCertificate from the signed data
    UniqueCERTCertificate certFromDER(
      CERT_NewTempCertificate(CERT_GetDefaultCertDB(), &cert->derCert, nullptr,
                              true /* perm */, true /* copyDER */));
    if (!certFromDER) {
      return mozilla::psm::GetXPCOMFromNSSError(PR_GetError());
    }

    // Save the cert in the DB
    rv = MapSECStatus(PK11_ImportCert(slot.get(), certFromDER.get(),
                                      CK_INVALID_HANDLE, mNickname.get(),
                                      false /* unused */));
    if (NS_FAILED(rv)) {
      return rv;
    }

    // We should now have cert in the DB, read it back in nsIX509Cert form
    return GetFromDB();
  }
static
OSStatus _SecIdentityAddPreferenceItemWithName(
	SecKeychainRef keychainRef,
	SecIdentityRef identityRef,
	CFStringRef idString,
	SecKeychainItemRef *itemRef)
{
    // this is NOT exported, and called only from SecIdentityAddPreferenceItem (below), so no BEGIN/END macros here;
    // caller must handle exceptions

	if (!identityRef || !idString)
		return errSecParam;
	SecPointer<Certificate> cert(Identity::required(identityRef)->certificate());
	Item item(kSecGenericPasswordItemClass, 'aapl', 0, NULL, false);
	sint32 keyUsage = 0;

	// determine the account attribute
	//
	// This attribute must be synthesized from certificate label + pref item type + key usage,
	// as only the account and service attributes can make a generic keychain item unique.
	// For 'iprf' type items (but not 'cprf'), we append a trailing space. This insures that
	// we can save a certificate preference if an identity preference already exists for the
	// given service name, and vice-versa.
	// If the key usage is 0 (i.e. the normal case), we omit the appended key usage string.
	//
    CFStringRef labelStr = nil;
	cert->inferLabel(false, &labelStr);
	if (!labelStr) {
        return errSecDataTooLarge; // data is "in a format which cannot be displayed"
	}
	CFIndex accountUTF8Len = CFStringGetMaximumSizeForEncoding(CFStringGetLength(labelStr), kCFStringEncodingUTF8) + 1;
	const char *templateStr = "%s [key usage 0x%X]";
	const int keyUsageMaxStrLen = 8;
	accountUTF8Len += strlen(templateStr) + keyUsageMaxStrLen;
	char accountUTF8[accountUTF8Len];
    if (!CFStringGetCString(labelStr, accountUTF8, accountUTF8Len-1, kCFStringEncodingUTF8))
		accountUTF8[0] = (char)'\0';
	if (keyUsage)
		snprintf(accountUTF8, accountUTF8Len-1, templateStr, accountUTF8, keyUsage);
	snprintf(accountUTF8, accountUTF8Len-1, "%s ", accountUTF8);
    CssmData account(const_cast<char *>(accountUTF8), strlen(accountUTF8));
    CFRelease(labelStr);

	// service attribute (name provided by the caller)
	CFIndex serviceUTF8Len = CFStringGetMaximumSizeForEncoding(CFStringGetLength(idString), kCFStringEncodingUTF8) + 1;;
	char serviceUTF8[serviceUTF8Len];
    if (!CFStringGetCString(idString, serviceUTF8, serviceUTF8Len-1, kCFStringEncodingUTF8))
        serviceUTF8[0] = (char)'\0';
    CssmData service(const_cast<char *>(serviceUTF8), strlen(serviceUTF8));

	// set item attribute values
	item->setAttribute(Schema::attributeInfo(kSecServiceItemAttr), service);
	item->setAttribute(Schema::attributeInfo(kSecLabelItemAttr), service);
	item->setAttribute(Schema::attributeInfo(kSecTypeItemAttr), (FourCharCode)'iprf');
	item->setAttribute(Schema::attributeInfo(kSecAccountItemAttr), account);
	item->setAttribute(Schema::attributeInfo(kSecScriptCodeItemAttr), keyUsage);

	// generic attribute (store persistent certificate reference)
	CFDataRef pItemRef = nil;
	OSStatus status = SecKeychainItemCreatePersistentReference((SecKeychainItemRef)cert->handle(), &pItemRef);
	if (!pItemRef)
		status = errSecInvalidItemRef;
	if (status)
		 return status;
	const UInt8 *dataPtr = CFDataGetBytePtr(pItemRef);
	CFIndex dataLen = CFDataGetLength(pItemRef);
	CssmData pref(const_cast<void *>(reinterpret_cast<const void *>(dataPtr)), dataLen);
	item->setAttribute(Schema::attributeInfo(kSecGenericItemAttr), pref);
	CFRelease(pItemRef);

	Keychain keychain = nil;
	try {
        keychain = Keychain::optional(keychainRef);
        if (!keychain->exists())
            MacOSError::throwMe(errSecNoSuchKeychain);	// Might be deleted or not available at this time.
    }
    catch(...) {
        keychain = globals().storageManager.defaultKeychainUI(item);
    }

	try {
		keychain->add(item);
	}
	catch (const MacOSError &err) {
		if (err.osStatus() != errSecDuplicateItem)
			throw; // if item already exists, fall through to update
	}

	item->update();

    if (itemRef)
		*itemRef = item->handle();

    return status;
}
Esempio n. 27
0
bool Servatrice::initServer()
{
    serverName = settings->value("server/name").toString();
    serverId = settings->value("server/id", 0).toInt();
    bool regServerOnly = settings->value("server/regonly", 0).toBool();
        
    const QString authenticationMethodStr = settings->value("authentication/method").toString();
    if (authenticationMethodStr == "sql") {
        authenticationMethod = AuthenticationSql;
    } else {
        if (regServerOnly) {
            qDebug() << "Registration only server enabled but no DB Connection : Error.";
            return false;   
        }
        authenticationMethod = AuthenticationNone;
    }
    
    QString dbTypeStr = settings->value("database/type").toString();
    if (dbTypeStr == "mysql")
        databaseType = DatabaseMySql;
    else
        databaseType = DatabaseNone;
    
    servatriceDatabaseInterface = new Servatrice_DatabaseInterface(-1, this);
    setDatabaseInterface(servatriceDatabaseInterface);
    
    if (databaseType != DatabaseNone) {
        settings->beginGroup("database");
        dbPrefix = settings->value("prefix").toString();
        servatriceDatabaseInterface->initDatabase("QMYSQL",
                              settings->value("hostname").toString(),
                              settings->value("database").toString(),
                              settings->value("user").toString(),
                              settings->value("password").toString());
        settings->endGroup();
        
        updateServerList();
        
        qDebug() << "Clearing previous sessions...";
        servatriceDatabaseInterface->clearSessionTables();
    }
    
    const QString roomMethod = settings->value("rooms/method").toString();
    if (roomMethod == "sql") {
        QSqlQuery query(servatriceDatabaseInterface->getDatabase());
        query.prepare("select id, name, descr, auto_join, join_message from " + dbPrefix + "_rooms order by id asc");
        servatriceDatabaseInterface->execSqlQuery(query);
        while (query.next()) {
            QSqlQuery query2(servatriceDatabaseInterface->getDatabase());
            query2.prepare("select name from " + dbPrefix + "_rooms_gametypes where id_room = :id_room");
            query2.bindValue(":id_room", query.value(0).toInt());
            servatriceDatabaseInterface->execSqlQuery(query2);
            QStringList gameTypes;
            while (query2.next())
                gameTypes.append(query2.value(0).toString());
            
            addRoom(new Server_Room(query.value(0).toInt(),
                                    query.value(1).toString(),
                                    query.value(2).toString(),
                                    query.value(3).toInt(),
                                    query.value(4).toString(),
                                    gameTypes,
                                    this
            ));
        }
    } else {
        int size = settings->beginReadArray("rooms/roomlist");
        for (int i = 0; i < size; ++i) {
            settings->setArrayIndex(i);
            
            QStringList gameTypes;
            int size2 = settings->beginReadArray("game_types");
                for (int j = 0; j < size2; ++j) {
                settings->setArrayIndex(j);
                gameTypes.append(settings->value("name").toString());
            }
            settings->endArray();
                
            Server_Room *newRoom = new Server_Room(
                i,
                settings->value("name").toString(),
                settings->value("description").toString(),
                settings->value("autojoin").toBool(),
                settings->value("joinmessage").toString(),
                gameTypes,
                this
            );
            addRoom(newRoom);
        }
        settings->endArray();
    }
    
    updateLoginMessage();
    
    maxGameInactivityTime = settings->value("game/max_game_inactivity_time").toInt();
    maxPlayerInactivityTime = settings->value("game/max_player_inactivity_time").toInt();
    
    maxUsersPerAddress = settings->value("security/max_users_per_address").toInt();
    messageCountingInterval = settings->value("security/message_counting_interval").toInt();
    maxMessageCountPerInterval = settings->value("security/max_message_count_per_interval").toInt();
    maxMessageSizePerInterval = settings->value("security/max_message_size_per_interval").toInt();
    maxGamesPerUser = settings->value("security/max_games_per_user").toInt();

	try { if (settings->value("servernetwork/active", 0).toInt()) {
		qDebug() << "Connecting to ISL network.";
		const QString certFileName = settings->value("servernetwork/ssl_cert").toString();
		const QString keyFileName = settings->value("servernetwork/ssl_key").toString();
		qDebug() << "Loading certificate...";
		QFile certFile(certFileName);
		if (!certFile.open(QIODevice::ReadOnly))
			throw QString("Error opening certificate file: %1").arg(certFileName);
		QSslCertificate cert(&certFile);
#if QT_VERSION < 0x050000
		if (!cert.isValid())
			throw(QString("Invalid certificate."));
#else
		const QDateTime currentTime = QDateTime::currentDateTime();
		if(currentTime < cert.effectiveDate() ||
			currentTime > cert.expiryDate() ||
			cert.isBlacklisted())
			throw(QString("Invalid certificate."));
#endif
		qDebug() << "Loading private key...";
		QFile keyFile(keyFileName);
		if (!keyFile.open(QIODevice::ReadOnly))
			throw QString("Error opening private key file: %1").arg(keyFileName);
		QSslKey key(&keyFile, QSsl::Rsa, QSsl::Pem, QSsl::PrivateKey);
		if (key.isNull())
			throw QString("Invalid private key.");
		
		QMutableListIterator<ServerProperties> serverIterator(serverList);
		while (serverIterator.hasNext()) {
			const ServerProperties &prop = serverIterator.next();
			if (prop.cert == cert) {
				serverIterator.remove();
				continue;
			}
			
			QThread *thread = new QThread;
			thread->setObjectName("isl_" + QString::number(prop.id));
			connect(thread, SIGNAL(finished()), thread, SLOT(deleteLater()));
			
			IslInterface *interface = new IslInterface(prop.id, prop.hostname, prop.address.toString(), prop.controlPort, prop.cert, cert, key, this);
			interface->moveToThread(thread);
			connect(interface, SIGNAL(destroyed()), thread, SLOT(quit()));
			
			thread->start();
			QMetaObject::invokeMethod(interface, "initClient", Qt::BlockingQueuedConnection);
		}
			
		const int networkPort = settings->value("servernetwork/port", 14747).toInt();
		qDebug() << "Starting ISL server on port" << networkPort;
		
		islServer = new Servatrice_IslServer(this, cert, key, this);
		if (islServer->listen(QHostAddress::Any, networkPort))
			qDebug() << "ISL server listening.";
		else
			throw QString("islServer->listen()");
	} } catch (QString error) {
		qDebug() << "ERROR --" << error;
		return false;
	}
	
	pingClock = new QTimer(this);
	connect(pingClock, SIGNAL(timeout()), this, SIGNAL(pingClockTimeout()));
	pingClock->start(1000);
	
	int statusUpdateTime = settings->value("server/statusupdate").toInt();
	statusUpdateClock = new QTimer(this);
	connect(statusUpdateClock, SIGNAL(timeout()), this, SLOT(statusUpdate()));
	if (statusUpdateTime != 0) {
		qDebug() << "Starting status update clock, interval " << statusUpdateTime << " ms";
		statusUpdateClock->start(statusUpdateTime);
	}
	
	const int numberPools = settings->value("server/number_pools", 1).toInt();
	gameServer = new Servatrice_GameServer(this, numberPools, servatriceDatabaseInterface->getDatabase(), this);
	gameServer->setMaxPendingConnections(1000);
	const int gamePort = settings->value("server/port", 4747).toInt();
	qDebug() << "Starting server on port" << gamePort;
	if (gameServer->listen(QHostAddress::Any, gamePort))
		qDebug() << "Server listening.";
	else {
		qDebug() << "gameServer->listen(): Error.";
		return false;
	}
	return true;
}
Esempio n. 28
0
   void run(int argc, char* argv[], char* env[])
      {
      U_TRACE(5, "Application::run(%d,%p,%p)", argc, argv, env)

      UApplication::run(argc, argv, env);

      U_SYSCALL_VOID_NO_PARAM(xmlInitParser); // init libxml

      LIBXML_TEST_VERSION

      // manage options

      num_args = (argc - optind);

      U_INTERNAL_DUMP("optind = %d num_args = %d", optind, num_args)

      if (UApplication::isOptions()) cfg_str = opt['c'];

      // manage file configuration

      if (cfg_str.empty()) cfg_str = U_STRING_FROM_CONSTANT("XAdES.ini");

      // ----------------------------------------------------------------------------------------------------------------------------------
      // XAdES signature - configuration parameters
      // ----------------------------------------------------------------------------------------------------------------------------------
      // DigestAlgorithm   md2 | md5 | sha | sha1 | sha224 | sha256 | sha384 | sha512 | mdc2 | ripmed160
      //
      // SigningTime this property contains the time at which the signer claims to have performed the signing process (yes/no)
      // ClaimedRole this property contains claimed or certified roles assumed by the signer in creating the signature
      //
      // this property contains the indication of the purported place where the signer claims to have produced the signature
      // -------------------------------------------------------------------------------------------------------------------
      // ProductionPlaceCity
      // ProductionPlaceStateOrProvince
      // ProductionPlacePostalCode
      // ProductionPlaceCountryName
      // -------------------------------------------------------------------------------------------------------------------
      //
      // DataObjectFormatMimeType   this property identifies the format of a signed data object (when electronic signatures
      //                            are not exchanged in a restricted context) to enable the presentation to the verifier or
      //                            use by the verifier (text, sound or video) in exactly the same way as intended by the signer
      //
      // CAStore
      // ArchiveTimeStamp           the time-stamp token within this property covers the archive validation data
      //
      // SignatureTimeStamp         the time-stamp token within this property covers the digital signature value element
      // Schema                     the pathname XML Schema of XAdES
      // ----------------------------------------------------------------------------------------------------------------------------------

      cfg.UFile::setPath(cfg_str);

      UString x(U_CAPACITY);

      UServices::readEOF(STDIN_FILENO, x);

      if (x.empty()) U_ERROR("cannot read data from <stdin>");

      (void) document.reserve(x.size());

      UBase64::decode(x, document);

      if (document.empty()) U_ERROR("decoding data read failed");

      // manage arguments...

      if ( U_DATA_URI &&
          *U_DATA_URI == '\0')
         {
         U_ERROR("DATA_URI is mandatory");
         }

      if ( U_X509 &&
          *U_X509 == '\0')
         {
         U_ERROR("X509 is mandatory");
         }

      if ( U_KEY_HANDLE &&
          *U_KEY_HANDLE == '\0')
         {
         U_ERROR("KEY_HANDLE is mandatory");
         }

      UCertificate cert(UString(U_X509));

      if (cert.isValid() == false) U_ERROR("certificate not valid");

      U_INTERNAL_DUMP("U_CA_STORE = %S", U_CA_STORE)

      xades_c = (U_CA_STORE != U_NULLPTR);

      digest_algorithm = getOptionValue(U_DIGEST_ALGORITHM, "DigestAlgorithm");

      alg = u_dgst_get_algoritm(digest_algorithm.c_str());

      if (alg == -1) U_ERROR("I can't find the digest algorithm for: %s", digest_algorithm.data());

      signing_time                       = getOptionValue(U_SIGNING_TIME,                       "SigningTime").strtol();
      claimed_role                       = getOptionValue(U_CLAIMED_ROLE,                       "ClaimedRole");
      production_place_city              = getOptionValue(U_PRODUCTION_PLACE_CITY,              "ProductionPlaceCity");
      production_place_state_or_province = getOptionValue(U_PRODUCTION_PLACE_STATE_OR_PROVINCE, "ProductionPlaceStateOrProvince");
      production_place_postal_code       = getOptionValue(U_PRODUCTION_PLACE_POSTAL_CODE,       "ProductionPlacePostalCode");
      production_place_country_name      = getOptionValue(U_PRODUCTION_PLACE_COUNTRY_NAME,      "ProductionPlaceCountryName");
      data_object_format_mimetype        = getOptionValue("",                                   "DataObjectFormatMimeType");

      if (xades_c == false) num_ca = 0;
      else
         {
         // XAdES-C
         // -------------------------------------------------------------------------------------------------------------  
         str_CApath          = getOptionValue(U_CA_STORE,            "CAStore");
         signature_timestamp = getOptionValue(U_SIGNATURE_TIMESTAMP, "SignatureTimeStamp");

         if (str_CApath.empty() ||
             UServices::setupOpenSSLStore(U_NULLPTR, str_CApath.c_str()) == false)
            {
            U_ERROR("error on setting CA Store: %S", str_CApath.data());
            }

         num_ca = cert.getSignerCertificates(vec_ca, U_NULLPTR, 0);

         if (UCertificate::verify_result == false)
            {
            UServices::setVerifyStatus();

            U_ERROR("error on verifying the certificate: %.*s", u_buffer_len, u_buffer);
            }
         // -------------------------------------------------------------------------------------------------------------  
         }

      u_base64_max_columns  = U_OPENSSL_BASE64_MAX_COLUMN;
      U_line_terminator_len = 2;

      UString modulus          = cert.getModulus(),
              exponent         = cert.getExponent();
              X509IssuerName   = cert.getIssuerForLDAP(),
              X509SubjectName  = cert.getSubjectForLDAP(),
              X509Certificate  = cert.getEncoded("DER");
              X509SerialNumber = cert.getSerialNumber();

      UString X509CertificateValue(U_CAPACITY), KeyInfo(U_CAPACITY);

      UBase64::encode(X509Certificate, X509CertificateValue);

      u_base64_max_columns = 0;

      KeyInfo.snprintf(U_CONSTANT_TO_PARAM(U_XMLDSIG_KEYINFO_TEMPLATE),
                       U_STRING_TO_TRACE(modulus),
                       U_STRING_TO_TRACE(exponent),
                       U_STRING_TO_TRACE(X509SubjectName),
                       U_STRING_TO_TRACE(X509IssuerName),
                       X509SerialNumber,
                       U_STRING_TO_TRACE(X509CertificateValue));

      UString ObjectDigestValue(200U),
              Reference(U_CAPACITY), dataObjectFormat(U_CAPACITY),
              XMLDSIGReference(U_CAPACITY), XMLDSIGReferenceC14N(U_CAPACITY);

      // ---------------------------------------------------------------------------------------------------------------
      // check for OOffice or MS-Word document...
      // ---------------------------------------------------------------------------------------------------------------
      utility.handlerConfig(cfg);

      (void) utility.checkDocument(document, U_DATA_URI, true);
      // ---------------------------------------------------------------------------------------------------------------

      for (uint32_t i = 0, n = utility.vdocument.size(); i < n; ++i)
         {
         uri       = utility.vuri[i];
         to_digest = utility.vdocument[i];

         // ---------------------------------------------------------------------------------------------------------------
         // 2. Compute the message digest of the text, m = Hash(C).
         // ---------------------------------------------------------------------------------------------------------------
         ObjectDigestValue.setEmpty();

         UServices::generateDigest(alg, 0, to_digest, ObjectDigestValue, true);
         // ---------------------------------------------------------------------------------------------------------------

         Reference.snprintf(U_CONSTANT_TO_PARAM(U_XMLDSIG_REFERENCE_TEMPLATE), uri.c_str(),
                            U_STRING_TO_TRACE(digest_algorithm),
                            U_STRING_TO_TRACE(ObjectDigestValue));

         XMLDSIGReference     +=                        Reference;
         XMLDSIGReferenceC14N += UXML2Document::xmlC14N(Reference);

         if (data_object_format_mimetype.empty() == false)
            {
            dataObjectFormat.snprintf(U_CONSTANT_TO_PARAM(U_XADES_DATA_OBJECT_FORMAT_TEMPLATE), uri.c_str(), U_STRING_TO_TRACE(data_object_format_mimetype));

            DataObjectFormat += dataObjectFormat;
            }
         }

      setXAdESReference(); // XAdES management

      // ---------------------------------------------------------------------------------------------------------------
      // 3. Encapsulate the message digest in an XML <SignedInfo> element, SI, in canonicalized form.
      // ---------------------------------------------------------------------------------------------------------------
      UString SignedInfo(U_CONSTANT_SIZE(U_XMLDSIG_SIGNED_INFO_TEMPLATE) + XMLDSIGReference.size() + XAdESReference.size());

      SignedInfo.snprintf(U_CONSTANT_TO_PARAM(U_XMLDSIG_SIGNED_INFO_TEMPLATE),
                          U_STRING_TO_TRACE(digest_algorithm),
                          U_STRING_TO_TRACE(XMLDSIGReference),
                          U_STRING_TO_TRACE(XAdESReference));

      UString to_sign = UXML2Document::xmlC14N(SignedInfo);
      // ---------------------------------------------------------------------------------------------------------------

      // ---------------------------------------------------------------------------------------------------------------
      // 4. Compute the RSA signatureValue of the canonicalized <SignedInfo> element, SV = RsaSign(Ks, SI).
      // ---------------------------------------------------------------------------------------------------------------
      UString SignatureValue(U_CAPACITY), signatureTimeStamp(U_CAPACITY), archiveTimeStamp(U_CAPACITY);

      u_base64_max_columns = U_OPENSSL_BASE64_MAX_COLUMN;

      ENGINE* e;

#  ifdef _MSWINDOWS_
      e = UServices::loadEngine("HCSP", ENGINE_METHOD_RSA);
      x = U_KEY_HANDLE;
#  else
      e = U_NULLPTR;
      x = UFile::contentOf(UString(U_KEY_HANDLE));

      if (x.empty() ||
          (u_pkey = UServices::loadKey(x, U_NULLPTR, true, U_NULLPTR, e)) == U_NULLPTR)
         {
         U_ERROR("I can't load the private key: %S", U_KEY_HANDLE);
         }

#     ifdef HAVE_OPENSSL_98
      if (cert.matchPrivateKey(u_pkey) == false) U_ERROR("the private key doesn't matches the public key of the certificate");
#     endif

      x.clear();
#  endif

      UString sign = UServices::getSignatureValue(alg, to_sign, x, UString::getStringNull(), true, e);

      u_base64_max_columns = 0;

      SignatureValue.snprintf(U_CONSTANT_TO_PARAM(U_XMLDSIG_SIGNATURE_VALUE_TEMPLATE), U_STRING_TO_TRACE(sign));

      if (signature_timestamp.empty() == false)
         {
         to_digest = UXML2Document::xmlC14N(SignatureValue);

         UString token = getTimeStampToken(to_digest, signature_timestamp);

         signatureTimeStamp.snprintf(U_CONSTANT_TO_PARAM(U_XADES_SIGNATURE_TIMESTAMP_TEMPLATE), U_STRING_TO_TRACE(token));
         }

      // XAdES-C
      // -------------------------------------------------------------------------------------------------------------  
      if (xades_c) setXAdESUnsignedSignatureProperties();
      // -------------------------------------------------------------------------------------------------------------  

      (void) XAdESObject.reserve(U_CONSTANT_SIZE(U_XADES_TEMPLATE) +
                          signedProperties.size() +
                          unsignedSignatureProperties.size() +
                          archiveTimeStamp.size() +
                          signatureTimeStamp.size());

      XAdESObject.snprintf(U_CONSTANT_TO_PARAM(U_XADES_TEMPLATE),
                           U_STRING_TO_TRACE(signedProperties),
                           U_STRING_TO_TRACE(unsignedSignatureProperties),
                           U_STRING_TO_TRACE(archiveTimeStamp),
                           U_STRING_TO_TRACE(signatureTimeStamp));
      // ---------------------------------------------------------------------------------------------------------------

      // ---------------------------------------------------------------------------------------------------------------
      // 5. Compose the final XML document including the signatureValue, this time in non-canonicalized form.
      // ---------------------------------------------------------------------------------------------------------------
      UString output(U_CONSTANT_SIZE(U_XMLDSIG_TEMPLATE) + 8192U + 
                     SignedInfo.size() + SignatureValue.size() + XAdESObject.size());

      if (utility.ooffice)
         {
         OpenDocumentStart = U_STRING_FROM_CONSTANT("<document-signatures xmlns=\"urn:oasis:names:tc:opendocument:xmlns:digitalsignature:1.0\">");
         OpenDocumentEnd   = U_STRING_FROM_CONSTANT("</document-signatures>");
         }

      output.snprintf(U_CONSTANT_TO_PARAM(U_XMLDSIG_TEMPLATE),
                        U_STRING_TO_TRACE(OpenDocumentStart),
                        U_STRING_TO_TRACE(SignedInfo),
                        U_STRING_TO_TRACE(SignatureValue),
                        U_STRING_TO_TRACE(KeyInfo),
                        U_STRING_TO_TRACE(XAdESObject),
                        U_STRING_TO_TRACE(OpenDocumentEnd));
      // ---------------------------------------------------------------------------------------------------------------

      // ---------------------------------------------------------------------------------------------------------------
      // check for OOffice or MS-Word document...
      // ---------------------------------------------------------------------------------------------------------------
      utility.outputDocument(output);
      // ---------------------------------------------------------------------------------------------------------------
      }
Esempio n. 29
0
QStringList QCSP::containers( SslCertificate::KeyUsage usage )
{
	qWarning() << "Start enumerationg providers";
	QHash<QString,QPair<QString,QString> > certs;
	HCRYPTPROV h = 0;
	DWORD index = 0, type = 0, size = 0;
	while( CryptEnumProvidersW( index, 0, 0, &type, 0, &size ) )
	{
		QString provider( size / sizeof(wchar_t) - 1, 0 );
		if( !CryptEnumProvidersW( index++, 0, 0, &type, LPWSTR(provider.data()), &size ) )
			continue;

		qWarning() << "Found provider" << provider << "type" << type;
		if( type != PROV_RSA_FULL )
			continue;

		// its broken and does not play well with pkcs11
		if( provider.toLower().contains( "esteid" ) )
			continue;

		qWarning() << "Acquiring provider" << provider << "context";
		if( h )
			CryptReleaseContext( h, 0 );
		h = 0;
		if( !CryptAcquireContextW( &h, 0, LPCWSTR(provider.utf16()), type, CRYPT_SILENT ) )
			continue;

		qWarning() << "Checking if provider" << provider << "is HW";
		QByteArray imptype = QCSPPrivate::provParam( h, PP_IMPTYPE );
		if( imptype.isEmpty() || !(imptype[0] & CRYPT_IMPL_HARDWARE) )
			continue;

		qWarning() << "Enumerating provider " << provider << "containers";
		QStringList containers;
		QByteArray container = QCSPPrivate::provParam( h, PP_ENUMCONTAINERS, CRYPT_FIRST );
		while( !container.isEmpty() )
		{
			containers << container;
			container = QCSPPrivate::provParam( h, PP_ENUMCONTAINERS, CRYPT_NEXT );
		}
		qWarning() << "Provider" << provider << "containers" << containers;

		Q_FOREACH( const QString &container, containers )
		{
			if( h )
				CryptReleaseContext( h, 0 );
			h = 0;
			qWarning() << "Acquiring provider" << provider << "container" << container << "context";
			if( !CryptAcquireContextW( &h, LPCWSTR(container.utf16()), LPCWSTR(provider.utf16()), type, CRYPT_SILENT ) )
				continue;

			qWarning() << "Geting provider" << provider << "container" << container << "key";
			HCRYPTKEY key = 0;
			if( !CryptGetUserKey( h, usage == SslCertificate::NonRepudiation ? AT_SIGNATURE : AT_KEYEXCHANGE, &key ) )
				continue;

			qWarning() << "Reading provider" << provider << "container" << container << "cert";
			QSslCertificate cert( QCSPPrivate::keyParam( key, KP_CERTIFICATE, 0 ), QSsl::Der );
			CryptDestroyKey( key );

			if( cert.isNull() )
				continue;

			qWarning() << "Adding provider" << provider << "container" << container << "list";
			certs.insert( cert.subjectInfo( QSslCertificate::CommonName ), QPair<QString,QString>( provider, container ) );
		}
	}
	if( h )
		CryptReleaseContext( h, 0 );
	qWarning() << "End enumerationg providers";

	d->certs = certs;
	return d->certs.keys();
}
Esempio n. 30
0
signed int
main(signed int ac, char** av)
{
	SSL_CTX* 	ctx(nullptr);
	SSL_METHOD*	meth(nullptr);
	SSL*		ssl(nullptr);
	signed long	sflags(0);
	signed int	sockfd(-1);
	signed int	retval(-1);
	std::string	host("");
	std::string	port("");
	std::string key("");
	std::string cert("");
	std::string	store("");
	std::string root("");

	::SSL_library_init();
	::OpenSSL_add_all_algorithms();
	::SSL_load_error_strings();

	sflags = ( 	SSL_OP_NO_SSLv2 | SSL_OP_NO_SSLv3 | SSL_OP_NO_TLSv1 | 
				SSL_OP_NO_TLSv1_1 | SSL_OP_CIPHER_SERVER_PREFERENCE | 
				SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION );

	if (7 != ac) {
		std::cerr << "Usage: " << av[0] << " <host> <port> <certificate> <key> <root certificate> <certificate store>" << std::endl;
		return EXIT_FAILURE;
	}

	host 	= av[1];
	port 	= av[2];
	cert	= av[3];
	key 	= av[4];
	root	= av[5];
	store	= av[6];

	meth	= const_cast< SSL_METHOD* >(::TLSv1_2_client_method());
	ctx		= ::SSL_CTX_new(meth);

	if (nullptr == meth) {
		::ERR_print_errors_fp(stderr);
		return EXIT_FAILURE;
	}

	::SSL_CTX_set_options(ctx, sflags);

	if (0 >= ::SSL_CTX_use_certificate_file(ctx, cert.c_str(), SSL_FILETYPE_PEM)) {
		::ERR_print_errors_fp(stderr);
		return EXIT_FAILURE;
	}

	if (0 >= ::SSL_CTX_use_PrivateKey_file(ctx, key.c_str(), SSL_FILETYPE_PEM)) {
		::ERR_print_errors_fp(stderr);
		return EXIT_FAILURE;
	}

	if (! ::SSL_CTX_check_private_key(ctx)) {
		std::cerr << "Private key does not match certificate" << std::endl;
		return EXIT_FAILURE;
	}

	if (! ::SSL_CTX_load_verify_locations(ctx, root.c_str(), store.c_str())) {
		std::cerr << "Load certificate store location failure" << std::endl;
		return EXIT_FAILURE;
	}

	::SSL_CTX_set_verify(ctx, SSL_VERIFY_PEER | SSL_VERIFY_FAIL_IF_NO_PEER_CERT, nullptr); //&verify_cb);
	::SSL_CTX_set_verify_depth(ctx, 5);

	std::cout << "Connecting to: " << host << ":" << port << std::endl;

	sockfd = open_connection(host, port);

	if (0 > sockfd) 
		return EXIT_FAILURE;

	ssl = SSL_new(ctx);
	::SSL_set_fd(ssl, sockfd);

	do {
		retval = ::ERR_get_error();
		
		if (0 != retval) 
			std::cerr << "SSL ERR: " << ::ERR_reason_error_string(retval) << std::endl;

	} while (0 != retval);

	retval = ::SSL_connect(ssl);

	if (1 != retval) {
		std::cerr << "Error in SSL_connect()" << std::endl;
		::ERR_print_errors_fp(stderr);


	} else {
		X509* 			ccert(::SSL_get_peer_certificate(ssl));
		char* 			line(nullptr);
		char 			buf[4096] = {0};
		signed int		len(-1);
		struct in_addr	ia;
		struct in6_addr	i6a;
		std::vector< ip_addr_t > avec;
		std::vector< port_t >	pvec;

		//message_t		msg(OP_SCAN_STATUS, 0x4141414141414141);


		if (0 >= ::inet_pton(AF_INET, "127.0.0.0", &ia)) {
			std::cerr << "inet_pton() error: " << ::strerror(errno) << std::endl;
			return EXIT_FAILURE;
		}

		avec.push_back(ip_addr_t(ia, 24));
		
		if (0 >= ::inet_pton(AF_INET, "192.0.0.0", &ia)) {
			std::cerr << "inet_pton() error: " << ::strerror(errno) << std::endl;
			return EXIT_FAILURE;
		}

		avec.push_back(ip_addr_t(ia, 8));

		if (0 >= ::inet_pton(AF_INET6, "fe80:20c:29ff:feee:4b72::1", &i6a)) {
			std::cerr << "inet_pton() error: " << ::strerror(errno) << std::endl;
			return EXIT_FAILURE;
		}

		avec.push_back(ip_addr_t(i6a, 120));

		if (0 >= ::inet_pton(AF_INET, "10.0.0.1", &ia)) {
			std::cerr << "inet_pton() error: " << ::strerror(errno) << std::endl;
			return EXIT_FAILURE;
		}

		avec.push_back(ip_addr_t(ia));

		if (0 >= ::inet_pton(AF_INET6, "::1", &i6a)) {
			std::cerr << "inet_pton() error: " << ::strerror(errno) << std::endl;
			return EXIT_FAILURE;
		}

		avec.push_back(ip_addr_t(i6a));
		pvec.push_back(port_t(PORT_PROTO_TCP, 80));
		pvec.push_back(port_t(PORT_PROTO_TCP, 443));
		pvec.push_back(port_t(PORT_PROTO_TCP, 143));
		pvec.push_back(port_t(PORT_PROTO_TCP, 22));
		pvec.push_back(port_t(PORT_PROTO_TCP, 139));
		pvec.push_back(port_t(PORT_PROTO_TCP, 31336));
		pvec.push_back(port_t(PORT_PROTO_TCP, 15));

		message_t msg(avec, pvec);

		if (X509_V_OK != ::SSL_get_verify_result(ssl)) 
			std::cout << "Certificate validation failed" << std::endl;
		else
			std::cout << "Certificate successfully validated" << std::endl;

		std::cout << "Connected with " << ::SSL_get_cipher(ssl) << " encryption." << std::endl;
	
		if (nullptr == ccert) {
			std::cerr << "ccert is nullptr" << std::endl;
			return EXIT_FAILURE;
		}

		line = ::X509_NAME_oneline(::X509_get_subject_name(ccert), 0, 0);
		std::cout << "Subject: " << line << std::endl;
		::free(line);
		line = ::X509_NAME_oneline(::X509_get_issuer_name(ccert), 0, 0); 
		std::cout << "Issuer: " << line << std::endl;
		::free(line);
		std::cout << "Version: " << ::X509_get_version(ccert) << std::endl;
		::X509_free(ccert);

		len = ::SSL_read(ssl, buf, sizeof(buf));

		if (0 < len && 4096 > len) {
			buf[len] = 0;
			std::cout << "buf: " << buf << std::endl;
		}

		std::vector< uint8_t > d(msg.data());
		::SSL_write(ssl, d.data(), d.size());
	}

	::close(sockfd);
	::SSL_CTX_free(ctx);
	return EXIT_SUCCESS;	
}