Beispiel #1
0
static gboolean ssl_connected(gpointer data, gint source,
                              b_input_condition cond)
{
	struct scd *conn = data;

	/* Right now we don't have any verification functionality for NSS. */

	if (conn->verify) {
		conn->func(conn->data, 1, NULL, cond);
		if (source >= 0) {
			closesocket(source);
		}
		g_free(conn->hostname);
		g_free(conn);

		return FALSE;
	}

	if (source == -1) {
		goto ssl_connected_failure;
	}

	/* Until we find out how to handle non-blocking I/O with NSS... */
	sock_make_blocking(conn->fd);

	conn->prfd = SSL_ImportFD(NULL, PR_ImportTCPSocket(source));
	if (!conn->prfd) {
		goto ssl_connected_failure;
	}
	SSL_OptionSet(conn->prfd, SSL_SECURITY, PR_TRUE);
	SSL_OptionSet(conn->prfd, SSL_HANDSHAKE_AS_CLIENT, PR_TRUE);
	SSL_BadCertHook(conn->prfd, (SSLBadCertHandler) nss_bad_cert, NULL);
	SSL_AuthCertificateHook(conn->prfd, (SSLAuthCertificate) nss_auth_cert,
	                        (void *) CERT_GetDefaultCertDB());
	SSL_SetURL(conn->prfd, conn->hostname);
	SSL_ResetHandshake(conn->prfd, PR_FALSE);

	if (SSL_ForceHandshake(conn->prfd)) {
		goto ssl_connected_failure;
	}

	conn->established = TRUE;
	conn->func(conn->data, 0, conn, cond);
	return FALSE;

ssl_connected_failure:

	conn->func(conn->data, 0, NULL, cond);

	if (conn->prfd) {
		PR_Close(conn->prfd);
	} else if (source >= 0) {
		/* proxy_disconnect() would be redundant here */
		closesocket(source);
	}
	g_free(conn->hostname);
	g_free(conn);

	return FALSE;
}
/** Create socket. If ssl is >0, socket is ssl enabled.
  @param ssl Enable ssl (Client, SSL2+3, no TLS, compatible hello) if PR_TRUE, otherwise no.
  @param ipv6 New socket will be IPv4 if this value is 0, otherwise it will be ipv6
  @return NULL on error, otherwise socket.
*/
static PRFileDesc *create_socket(int ssl,int ipv6) {
  PRFileDesc *res_socket;

  res_socket=PR_OpenTCPSocket((ipv6?PR_AF_INET6:PR_AF_INET));
  if (res_socket==NULL) {
    print_nspr_error();

    return NULL;
  }

  if (!ssl) return res_socket;

  if (!(res_socket=SSL_ImportFD(NULL,res_socket))) {
    print_nspr_error();

    return NULL;
  }

  if ((SSL_OptionSet(res_socket,SSL_SECURITY,ssl)!=SECSuccess) ||
      (SSL_OptionSet(res_socket,SSL_HANDSHAKE_AS_SERVER,PR_FALSE)!=SECSuccess) ||
      (SSL_OptionSet(res_socket,SSL_HANDSHAKE_AS_CLIENT,PR_TRUE)!=SECSuccess) ||
      (SSL_OptionSet(res_socket,SSL_ENABLE_SSL2,ssl)!=SECSuccess) ||
      (SSL_OptionSet(res_socket,SSL_ENABLE_SSL3,ssl)!=SECSuccess) ||
      (SSL_OptionSet(res_socket,SSL_ENABLE_TLS,PR_FALSE)!=SECSuccess) ||
      (SSL_OptionSet(res_socket,SSL_V2_COMPATIBLE_HELLO,ssl)!=SECSuccess) ||
      (SSL_SetPKCS11PinArg(res_socket,NULL)==-1) ||
      (SSL_AuthCertificateHook(res_socket,SSL_AuthCertificate,CERT_GetDefaultCertDB())!=SECSuccess) ||
      (SSL_BadCertHook(res_socket,nss_bad_cert_hook,NULL)!=SECSuccess)) {
    print_nspr_error();

    if (PR_Close(res_socket)!=PR_SUCCESS) {
      print_nspr_error();
    }

    return NULL;
  }

  return res_socket;
}
Beispiel #3
0
static gboolean ssl_connected( gpointer data, gint source, b_input_condition cond )
{
	struct scd *conn = data;
	
	if( source == -1 )
		goto ssl_connected_failure;
	
	/* Until we find out how to handle non-blocking I/O with NSS... */
	sock_make_blocking( conn->fd );
	
	conn->prfd = SSL_ImportFD(NULL, PR_ImportTCPSocket(source));
	SSL_OptionSet(conn->prfd, SSL_SECURITY, PR_TRUE);
	SSL_OptionSet(conn->prfd, SSL_HANDSHAKE_AS_CLIENT, PR_TRUE);
	SSL_BadCertHook(conn->prfd, (SSLBadCertHandler)nss_bad_cert, NULL);
	SSL_AuthCertificateHook(conn->prfd, (SSLAuthCertificate)nss_auth_cert, (void *)CERT_GetDefaultCertDB());
	SSL_ResetHandshake(conn->prfd, PR_FALSE);

	if (SSL_ForceHandshake(conn->prfd)) {
		goto ssl_connected_failure;
	}
	
	
	conn->established = TRUE;
	conn->func( conn->data, conn, cond );
	return FALSE;
	
	ssl_connected_failure:
	
	conn->func( conn->data, NULL, cond );
	
	PR_Close( conn -> prfd );
	if( source >= 0 ) closesocket( source );
	g_free( conn );
	
	return FALSE;
}
Beispiel #4
0
CURLcode Curl_nss_connect(struct connectdata *conn, int sockindex)
{
  PRErrorCode err = 0;
  PRFileDesc *model = NULL;
  PRBool ssl2 = PR_FALSE;
  PRBool ssl3 = PR_FALSE;
  PRBool tlsv1 = PR_FALSE;
  PRBool ssl_no_cache;
  PRBool ssl_cbc_random_iv;
  struct SessionHandle *data = conn->data;
  curl_socket_t sockfd = conn->sock[sockindex];
  struct ssl_connect_data *connssl = &conn->ssl[sockindex];
  CURLcode curlerr;
  const int *cipher_to_enable;
  PRSocketOptionData sock_opt;
  long time_left;
  PRUint32 timeout;

  if(connssl->state == ssl_connection_complete)
    return CURLE_OK;

  connssl->data = data;

  /* list of all NSS objects we need to destroy in Curl_nss_close() */
  connssl->obj_list = Curl_llist_alloc(nss_destroy_object);
  if(!connssl->obj_list)
    return CURLE_OUT_OF_MEMORY;

  /* FIXME. NSS doesn't support multiple databases open at the same time. */
  PR_Lock(nss_initlock);
  curlerr = nss_init(conn->data);
  if(CURLE_OK != curlerr) {
    PR_Unlock(nss_initlock);
    goto error;
  }

  curlerr = CURLE_SSL_CONNECT_ERROR;

  if(!mod) {
    char *configstring = aprintf("library=%s name=PEM", pem_library);
    if(!configstring) {
      PR_Unlock(nss_initlock);
      goto error;
    }
    mod = SECMOD_LoadUserModule(configstring, NULL, PR_FALSE);
    free(configstring);

    if(!mod || !mod->loaded) {
      if(mod) {
        SECMOD_DestroyModule(mod);
        mod = NULL;
      }
      infof(data, "WARNING: failed to load NSS PEM library %s. Using "
            "OpenSSL PEM certificates will not work.\n", pem_library);
    }
  }

  PK11_SetPasswordFunc(nss_get_password);
  PR_Unlock(nss_initlock);

  model = PR_NewTCPSocket();
  if(!model)
    goto error;
  model = SSL_ImportFD(NULL, model);

  /* make the socket nonblocking */
  sock_opt.option = PR_SockOpt_Nonblocking;
  sock_opt.value.non_blocking = PR_TRUE;
  if(PR_SetSocketOption(model, &sock_opt) != PR_SUCCESS)
    goto error;

  if(SSL_OptionSet(model, SSL_SECURITY, PR_TRUE) != SECSuccess)
    goto error;
  if(SSL_OptionSet(model, SSL_HANDSHAKE_AS_SERVER, PR_FALSE) != SECSuccess)
    goto error;
  if(SSL_OptionSet(model, SSL_HANDSHAKE_AS_CLIENT, PR_TRUE) != SECSuccess)
    goto error;

  /* do not use SSL cache if we are not going to verify peer */
  ssl_no_cache = (data->set.ssl.verifypeer) ? PR_FALSE : PR_TRUE;
  if(SSL_OptionSet(model, SSL_NO_CACHE, ssl_no_cache) != SECSuccess)
    goto error;

  switch (data->set.ssl.version) {
  default:
  case CURL_SSLVERSION_DEFAULT:
    ssl3 = PR_TRUE;
    if(data->state.ssl_connect_retry)
      infof(data, "TLS disabled due to previous handshake failure\n");
    else
      tlsv1 = PR_TRUE;
    break;
  case CURL_SSLVERSION_TLSv1:
    tlsv1 = PR_TRUE;
    break;
  case CURL_SSLVERSION_SSLv2:
    ssl2 = PR_TRUE;
    break;
  case CURL_SSLVERSION_SSLv3:
    ssl3 = PR_TRUE;
    break;
  }

  if(SSL_OptionSet(model, SSL_ENABLE_SSL2, ssl2) != SECSuccess)
    goto error;
  if(SSL_OptionSet(model, SSL_ENABLE_SSL3, ssl3) != SECSuccess)
    goto error;
  if(SSL_OptionSet(model, SSL_ENABLE_TLS, tlsv1) != SECSuccess)
    goto error;

  if(SSL_OptionSet(model, SSL_V2_COMPATIBLE_HELLO, ssl2) != SECSuccess)
    goto error;

  ssl_cbc_random_iv = !data->set.ssl_enable_beast;
#ifdef SSL_CBC_RANDOM_IV
  /* unless the user explicitly asks to allow the protocol vulnerability, we
     use the work-around */
  if(SSL_OptionSet(model, SSL_CBC_RANDOM_IV, ssl_cbc_random_iv) != SECSuccess)
    infof(data, "warning: failed to set SSL_CBC_RANDOM_IV = %d\n",
          ssl_cbc_random_iv);
#else
  if(ssl_cbc_random_iv)
    infof(data, "warning: support for SSL_CBC_RANDOM_IV not compiled in\n");
#endif

  /* reset the flag to avoid an infinite loop */
  data->state.ssl_connect_retry = FALSE;

  /* enable all ciphers from enable_ciphers_by_default */
  cipher_to_enable = enable_ciphers_by_default;
  while(SSL_NULL_WITH_NULL_NULL != *cipher_to_enable) {
    if(SSL_CipherPrefSet(model, *cipher_to_enable, PR_TRUE) != SECSuccess) {
      curlerr = CURLE_SSL_CIPHER;
      goto error;
    }
    cipher_to_enable++;
  }

  if(data->set.ssl.cipher_list) {
    if(set_ciphers(data, model, data->set.ssl.cipher_list) != SECSuccess) {
      curlerr = CURLE_SSL_CIPHER;
      goto error;
    }
  }

  if(!data->set.ssl.verifypeer && data->set.ssl.verifyhost)
    infof(data, "warning: ignoring value of ssl.verifyhost\n");

  /* bypass the default SSL_AuthCertificate() hook in case we do not want to
   * verify peer */
  if(SSL_AuthCertificateHook(model, nss_auth_cert_hook, conn) != SECSuccess)
    goto error;

  data->set.ssl.certverifyresult=0; /* not checked yet */
  if(SSL_BadCertHook(model, BadCertHandler, conn) != SECSuccess)
    goto error;

  if(SSL_HandshakeCallback(model, HandshakeCallback, NULL) != SECSuccess)
    goto error;

  if(data->set.ssl.verifypeer) {
    const CURLcode rv = nss_load_ca_certificates(conn, sockindex);
    if(CURLE_OK != rv) {
      curlerr = rv;
      goto error;
    }
  }

  if(data->set.ssl.CRLfile) {
    if(SECSuccess != nss_load_crl(data->set.ssl.CRLfile)) {
      curlerr = CURLE_SSL_CRL_BADFILE;
      goto error;
    }
    infof(data,
          "  CRLfile: %s\n",
          data->set.ssl.CRLfile ? data->set.ssl.CRLfile : "none");
  }

  if(data->set.str[STRING_CERT]) {
    char *nickname = dup_nickname(data, STRING_CERT);
    if(nickname) {
      /* we are not going to use libnsspem.so to read the client cert */
      connssl->obj_clicert = NULL;
    }
    else {
      CURLcode rv = cert_stuff(conn, sockindex, data->set.str[STRING_CERT],
                               data->set.str[STRING_KEY]);
      if(CURLE_OK != rv) {
        /* failf() is already done in cert_stuff() */
        curlerr = rv;
        goto error;
      }
    }

    /* store the nickname for SelectClientCert() called during handshake */
    connssl->client_nickname = nickname;
  }
  else
    connssl->client_nickname = NULL;

  if(SSL_GetClientAuthDataHook(model, SelectClientCert,
                               (void *)connssl) != SECSuccess) {
    curlerr = CURLE_SSL_CERTPROBLEM;
    goto error;
  }

  /* Import our model socket  onto the existing file descriptor */
  connssl->handle = PR_ImportTCPSocket(sockfd);
  connssl->handle = SSL_ImportFD(model, connssl->handle);
  if(!connssl->handle)
    goto error;

  PR_Close(model); /* We don't need this any more */
  model = NULL;

  /* This is the password associated with the cert that we're using */
  if(data->set.str[STRING_KEY_PASSWD]) {
    SSL_SetPKCS11PinArg(connssl->handle, data->set.str[STRING_KEY_PASSWD]);
  }

  /* Force handshake on next I/O */
  SSL_ResetHandshake(connssl->handle, /* asServer */ PR_FALSE);

  SSL_SetURL(connssl->handle, conn->host.name);

  /* check timeout situation */
  time_left = Curl_timeleft(data, NULL, TRUE);
  if(time_left < 0L) {
    failf(data, "timed out before SSL handshake");
    curlerr = CURLE_OPERATION_TIMEDOUT;
    goto error;
  }
  timeout = PR_MillisecondsToInterval((PRUint32) time_left);

  /* Force the handshake now */
  if(SSL_ForceHandshakeWithTimeout(connssl->handle, timeout) != SECSuccess) {
    if(conn->data->set.ssl.certverifyresult == SSL_ERROR_BAD_CERT_DOMAIN)
      curlerr = CURLE_PEER_FAILED_VERIFICATION;
    else if(conn->data->set.ssl.certverifyresult!=0)
      curlerr = CURLE_SSL_CACERT;
    goto error;
  }

  connssl->state = ssl_connection_complete;
  conn->recv[sockindex] = nss_recv;
  conn->send[sockindex] = nss_send;

  display_conn_info(conn, connssl->handle);

  if(data->set.str[STRING_SSL_ISSUERCERT]) {
    SECStatus ret = SECFailure;
    char *nickname = dup_nickname(data, STRING_SSL_ISSUERCERT);
    if(nickname) {
      /* we support only nicknames in case of STRING_SSL_ISSUERCERT for now */
      ret = check_issuer_cert(connssl->handle, nickname);
      free(nickname);
    }

    if(SECFailure == ret) {
      infof(data,"SSL certificate issuer check failed\n");
      curlerr = CURLE_SSL_ISSUER_ERROR;
      goto error;
    }
    else {
      infof(data, "SSL certificate issuer check ok\n");
    }
  }

  return CURLE_OK;

  error:
  /* reset the flag to avoid an infinite loop */
  data->state.ssl_connect_retry = FALSE;

  if(is_nss_error(curlerr)) {
    /* read NSPR error code */
    err = PR_GetError();
    if(is_cc_error(err))
      curlerr = CURLE_SSL_CERTPROBLEM;

    /* print the error number and error string */
    infof(data, "NSS error %d (%s)\n", err, nss_error_to_name(err));

    /* print a human-readable message describing the error if available */
    nss_print_error_message(data, err);
  }

  if(model)
    PR_Close(model);

    /* cleanup on connection failure */
    Curl_llist_destroy(connssl->obj_list, NULL);
    connssl->obj_list = NULL;

  if(ssl3 && tlsv1 && isTLSIntoleranceError(err)) {
    /* schedule reconnect through Curl_retry_request() */
    data->state.ssl_connect_retry = TRUE;
    infof(data, "Error in TLS handshake, trying SSLv3...\n");
    return CURLE_OK;
  }

  return curlerr;
}
PRFileDesc *
setupSSLSocket(PRNetAddr *addr)
{
	PRFileDesc         *tcpSocket;
	PRFileDesc         *sslSocket;
	PRSocketOptionData	socketOption;
	PRStatus            prStatus;
	SECStatus           secStatus;


	tcpSocket = PR_NewTCPSocket();
	if (tcpSocket == NULL) {
		errWarn("PR_NewTCPSocket");
	}

	/* Make the socket blocking. */
	socketOption.option	            = PR_SockOpt_Nonblocking;
	socketOption.value.non_blocking = PR_FALSE;

	prStatus = PR_SetSocketOption(tcpSocket, &socketOption);
	if (prStatus != PR_SUCCESS) {
		errWarn("PR_SetSocketOption");
		goto loser;
	} 


	/* Import the socket into the SSL layer. */
	sslSocket = SSL_ImportFD(NULL, tcpSocket);
	if (!sslSocket) {
		errWarn("SSL_ImportFD");
		goto loser;
	}

	/* Set configuration options. */
	secStatus = SSL_OptionSet(sslSocket, SSL_SECURITY, PR_TRUE);
	if (secStatus != SECSuccess) {
		errWarn("SSL_OptionSet:SSL_SECURITY");
		goto loser;
	}

	secStatus = SSL_OptionSet(sslSocket, SSL_HANDSHAKE_AS_CLIENT, PR_TRUE);
	if (secStatus != SECSuccess) {
		errWarn("SSL_OptionSet:SSL_HANDSHAKE_AS_CLIENT");
		goto loser;
	}

	/* Set SSL callback routines. */
	secStatus = SSL_GetClientAuthDataHook(sslSocket,
	                          (SSLGetClientAuthData)myGetClientAuthData,
	                          (void *)certNickname);
	if (secStatus != SECSuccess) {
		errWarn("SSL_GetClientAuthDataHook");
		goto loser;
	}

	secStatus = SSL_AuthCertificateHook(sslSocket,
	                                   (SSLAuthCertificate)myAuthCertificate,
                                       (void *)CERT_GetDefaultCertDB());
	if (secStatus != SECSuccess) {
		errWarn("SSL_AuthCertificateHook");
		goto loser;
	}

	secStatus = SSL_BadCertHook(sslSocket, 
	                           (SSLBadCertHandler)myBadCertHandler, NULL);
	if (secStatus != SECSuccess) {
		errWarn("SSL_BadCertHook");
		goto loser;
	}

	secStatus = SSL_HandshakeCallback(sslSocket, 
	                                  myHandshakeCallback,
	                                  NULL);
	if (secStatus != SECSuccess) {
		errWarn("SSL_HandshakeCallback");
		goto loser;
	}

	return sslSocket;

loser:

	PR_Close(tcpSocket);
	return NULL;
}
Beispiel #6
0
/**
 * Performs SSL handshake on a TCP socket.
 */
PRFileDesc *Connection::secureSocket(const std::string &certDBPasswd,
	const std::string &certNickName,
	bool alwaysTrustServerCert,
	PRFileDesc *rawSocket) {
	bool upgradeExisting = false;
	// Use object's socket if none passed
	if (rawSocket == static_cast<PRFileDesc *>(NULL)) {
		rawSocket = socket;
		upgradeExisting = true;
	}
	PRFileDesc *sslSocket = SSL_ImportFD(NULL, rawSocket);
	if (static_cast<PRFileDesc *>(NULL) != sslSocket) {
	    SECStatus secStatus = SECSuccess;
	    const char *sslMethodName;
	
	    // In case there was any communication on the socket
	    // before the upgrade we should call a reset
	    if (upgradeExisting) {
                sslMethodName = "SSL_ResetHandshake";
                secStatus = SSL_ResetHandshake(sslSocket, false);
	    }

	    if (SECSuccess == secStatus) {
                sslMethodName = "SSL_OptionSet";
                secStatus = SSL_OptionSet(sslSocket, SSL_SECURITY, PR_TRUE);
	    }

	    if (SECSuccess == secStatus) {
                secStatus = SSL_OptionSet(sslSocket,
                                      SSL_HANDSHAKE_AS_CLIENT, PR_TRUE);
                if (SECSuccess == secStatus && alwaysTrustServerCert) {
                    sslMethodName = "SSL_AuthCertificateHook";
                    secStatus = SSL_AuthCertificateHook(sslSocket, acceptAnyCert,
                                                    NULL);
                }

                if (SECSuccess == secStatus && certDBPasswd.size() > 0) {
                    sslMethodName = "SSL_SetPKCS11PinArg";
                    secStatus = SSL_SetPKCS11PinArg(sslSocket, certdbpasswd);
                }

                if (SECSuccess == secStatus) {
		    if (certNickName.size() > 0) {
                        certnickname = strdup(certNickName.c_str());
                    }
                    sslMethodName = "SSL_GetClientAuthDataHook";
                    secStatus = SSL_GetClientAuthDataHook(sslSocket,
                                                   NSS_GetClientAuthData,
                                                   static_cast<void *>(certnickname));
                }

                if (SECSuccess == secStatus) {
                    sslMethodName = "SSL_HandshakeCallback";
                    secStatus = SSL_HandshakeCallback(sslSocket,
                                (SSLHandshakeCallback)finishedHandshakeHandler,
                                 NULL);
		}
	    }

	    if (SECSuccess != secStatus) {
		PRErrorCode error = PR_GetError();

		PR_Close(sslSocket);
		throw NSPRException("Connection::secureSocket",
				sslMethodName, error);
	    }
	} else {
	    PRErrorCode error = PR_GetError();

	    PR_Close(rawSocket);
	    throw NSPRException("Connection::secureSocket", "SSL_ImportFD",
				error);
	}

	socket = sslSocket;
	return sslSocket;
}
// TODO: make sure this is called from STS. Otherwise
// we have thread safety issues
bool TransportLayerDtls::Setup() {
  CheckThread();
  SECStatus rv;

  if (!downward_) {
    MOZ_MTLOG(ML_ERROR, "DTLS layer with nothing below. This is useless");
    return false;
  }
  nspr_io_adapter_ = new TransportLayerNSPRAdapter(downward_);

  if (!identity_) {
    MOZ_MTLOG(ML_ERROR, "Can't start DTLS without an identity");
    return false;
  }

  if (verification_mode_ == VERIFY_UNSET) {
    MOZ_MTLOG(ML_ERROR,
              "Can't start DTLS without specifying a verification mode");
    return false;
  }

  if (transport_layer_identity == PR_INVALID_IO_LAYER) {
    transport_layer_identity = PR_GetUniqueIdentity("nssstreamadapter");
  }

  ScopedPRFileDesc pr_fd(PR_CreateIOLayerStub(transport_layer_identity,
                                              &TransportLayerMethods));
  MOZ_ASSERT(pr_fd != nullptr);
  if (!pr_fd)
    return false;
  pr_fd->secret = reinterpret_cast<PRFilePrivate *>(nspr_io_adapter_.get());

  ScopedPRFileDesc ssl_fd(DTLS_ImportFD(nullptr, pr_fd));
  MOZ_ASSERT(ssl_fd != nullptr);  // This should never happen
  if (!ssl_fd) {
    return false;
  }

  pr_fd.forget(); // ownership transfered to ssl_fd;

  if (role_ == CLIENT) {
    MOZ_MTLOG(ML_DEBUG, "Setting up DTLS as client");
    rv = SSL_GetClientAuthDataHook(ssl_fd, GetClientAuthDataHook,
                                   this);
    if (rv != SECSuccess) {
      MOZ_MTLOG(ML_ERROR, "Couldn't set identity");
      return false;
    }
  } else {
    MOZ_MTLOG(ML_DEBUG, "Setting up DTLS as server");
    // Server side
    rv = SSL_ConfigSecureServer(ssl_fd, identity_->cert(),
                                identity_->privkey(),
                                kt_rsa);
    if (rv != SECSuccess) {
      MOZ_MTLOG(ML_ERROR, "Couldn't set identity");
      return false;
    }

    // Insist on a certificate from the client
    rv = SSL_OptionSet(ssl_fd, SSL_REQUEST_CERTIFICATE, PR_TRUE);
    if (rv != SECSuccess) {
      MOZ_MTLOG(ML_ERROR, "Couldn't request certificate");
      return false;
    }

    rv = SSL_OptionSet(ssl_fd, SSL_REQUIRE_CERTIFICATE, PR_TRUE);
    if (rv != SECSuccess) {
      MOZ_MTLOG(ML_ERROR, "Couldn't require certificate");
      return false;
    }
  }

  // Require TLS 1.1 or 1.2. Perhaps some day in the future we will allow TLS
  // 1.0 for stream modes.
  SSLVersionRange version_range = {
    SSL_LIBRARY_VERSION_TLS_1_1,
    SSL_LIBRARY_VERSION_TLS_1_2
  };

  rv = SSL_VersionRangeSet(ssl_fd, &version_range);
  if (rv != SECSuccess) {
    MOZ_MTLOG(ML_ERROR, "Can't disable SSLv3");
    return false;
  }

  rv = SSL_OptionSet(ssl_fd, SSL_ENABLE_SESSION_TICKETS, PR_FALSE);
  if (rv != SECSuccess) {
    MOZ_MTLOG(ML_ERROR, "Couldn't disable session tickets");
    return false;
  }

  rv = SSL_OptionSet(ssl_fd, SSL_NO_CACHE, PR_TRUE);
  if (rv != SECSuccess) {
    MOZ_MTLOG(ML_ERROR, "Couldn't disable session caching");
    return false;
  }

  rv = SSL_OptionSet(ssl_fd, SSL_ENABLE_DEFLATE, PR_FALSE);
  if (rv != SECSuccess) {
    MOZ_MTLOG(ML_ERROR, "Couldn't disable deflate");
    return false;
  }

  rv = SSL_OptionSet(ssl_fd, SSL_ENABLE_RENEGOTIATION, SSL_RENEGOTIATE_NEVER);
  if (rv != SECSuccess) {
    MOZ_MTLOG(ML_ERROR, "Couldn't disable renegotiation");
    return false;
  }

  rv = SSL_OptionSet(ssl_fd, SSL_ENABLE_FALSE_START, PR_FALSE);
  if (rv != SECSuccess) {
    MOZ_MTLOG(ML_ERROR, "Couldn't disable false start");
    return false;
  }

  rv = SSL_OptionSet(ssl_fd, SSL_NO_LOCKS, PR_TRUE);
  if (rv != SECSuccess) {
    MOZ_MTLOG(ML_ERROR, "Couldn't disable locks");
    return false;
  }

  rv = SSL_OptionSet(ssl_fd, SSL_REUSE_SERVER_ECDHE_KEY, PR_FALSE);
  if (rv != SECSuccess) {
    MOZ_MTLOG(ML_ERROR, "Couldn't disable ECDHE key reuse");
    return false;
  }

  if (!SetupCipherSuites(ssl_fd)) {
    return false;
  }

  // Certificate validation
  rv = SSL_AuthCertificateHook(ssl_fd, AuthCertificateHook,
                               reinterpret_cast<void *>(this));
  if (rv != SECSuccess) {
    MOZ_MTLOG(ML_ERROR, "Couldn't set certificate validation hook");
    return false;
  }

  // Now start the handshake
  rv = SSL_ResetHandshake(ssl_fd, role_ == SERVER ? PR_TRUE : PR_FALSE);
  if (rv != SECSuccess) {
    MOZ_MTLOG(ML_ERROR, "Couldn't reset handshake");
    return false;
  }
  ssl_fd_ = ssl_fd.forget();

  // Finally, get ready to receive data
  downward_->SignalStateChange.connect(this, &TransportLayerDtls::StateChange);
  downward_->SignalPacketReceived.connect(this, &TransportLayerDtls::PacketReceived);

  if (downward_->state() == TS_OPEN) {
    Handshake();
  }

  return true;
}
static PRFileDesc *
setupSSLSocket(void)
{
  PRFileDesc         *tcpSocket;
  PRFileDesc         *sslSocket;
  PRSocketOptionData	socketOption;
  PRStatus            prStatus;
  SECStatus           secStatus;

  tcpSocket = PR_NewTCPSocket();
  if (tcpSocket == NULL)
    goto loser;

  /* Make the socket blocking. */
  socketOption.option = PR_SockOpt_Nonblocking;
  socketOption.value.non_blocking = PR_FALSE;

  prStatus = PR_SetSocketOption(tcpSocket, &socketOption);
  if (prStatus != PR_SUCCESS)
    goto loser;

  /* Import the socket into the SSL layer. */
  sslSocket = SSL_ImportFD(NULL, tcpSocket);
  if (!sslSocket)
    goto loser;

  /* Set configuration options. */
  secStatus = SSL_OptionSet(sslSocket, SSL_SECURITY, PR_TRUE);
  if (secStatus != SECSuccess)
    goto loser;

  secStatus = SSL_OptionSet(sslSocket, SSL_HANDSHAKE_AS_CLIENT, PR_TRUE);
  if (secStatus != SECSuccess)
    goto loser;

  /* Set SSL callback routines. */
#if 0 /* no client authentication */
  secStatus = SSL_GetClientAuthDataHook(sslSocket,
					(SSLGetClientAuthData)myGetClientAuthData,
					(void *)certNickname);
  if (secStatus != SECSuccess)
    goto loser;
#endif
#if 0 /* Use the default */
  secStatus = SSL_AuthCertificateHook(sslSocket,
				      (SSLAuthCertificate)myAuthCertificate,
				      (void *)CERT_GetDefaultCertDB());
  if (secStatus != SECSuccess)
    goto loser;
#endif

  secStatus = SSL_BadCertHook(sslSocket, (SSLBadCertHandler)badCertHandler, NULL);
  if (secStatus != SECSuccess)
    goto loser;

#if 0 /* No handshake callback */
  secStatus = SSL_HandshakeCallback(sslSocket, myHandshakeCallback, NULL);
  if (secStatus != SECSuccess)
    goto loser;
#endif

  return sslSocket;

 loser:
  if (tcpSocket)
    PR_Close(tcpSocket);
  return NULL;
}
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;
}
Beispiel #10
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;
}
Beispiel #11
0
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;
}