4

I am trying to setup my dart http server to run only with https. So I gather I need to use HttpServer.bindSecure but I'm not clear from the description what needs to be passed in as certificateName and whether requestClientCertificate being true makes it more or less secure, or has no impact on security what so ever. The small sample code at the top of the HttpServer page passes in certificateName: 'localhost_cert' but before that it does something with a database, but doesn't seem to use it in anyway. Can anyone explain in more detail what these values are and what they need to be in order to make them secure?

3

1 Answer 1

4

The requestClientCertificate parameter of bindSecure is used to specify a client certificate. Client certificates are used by servers to identify and authorize clients, which appears not to be the objective of this question. It should be noted that there is a known issue with using client certificates in Dart on IE9 and Windows 7.

The certificateName parameter is used to specify the nickname of a certificate that exists in your certificate database. You specify the certificate nickname using the -n <nickname> option when importing a certificate to your database using certutil.

Use the following steps to:

  • Install the NSS utility (including certutil),

  • Create a new certificate database in directory <dir> with a password <password>, and

  • Import your self-signed or purchased certificate identified by nickname <host> such that it can be used to create an HTTPS server using the following sample code. Though the nickname can be chosen arbitrarily, we use the host name in this example. These steps have been confirmed working in Ubuntu 14.04 and Dart SDK 1.6 through (currently last stable version) 1.8.3.

    1. Install the NSS utility
      sudo apt-get install libnss3-tools

    2. cd to the directory that will contain your certificate database
      cd <dir>

    3. Create a password file to use with the certificate database:
      echo "<password>" > pwdfile

    4. Create the certificate database
      certutil -N -d 'sql:./' -f pwdfile

    5. Either:

      • Generate a self-signed certificate:

        certutil -S -s "cn=<host>" -n "self signed for dart" -x -t "C,C,C" -m 1000 -v 120 -d "sql:./" -k rsa -g 2048 -f pwdfile

        where <host> is the host ("common name") for which to generate a certificate, for example "localhost"

      • Or, purchase a certificate by first creating a signing request for a real domain <host>, for example "myhost.com":

        certutil -R -s "CN=<host>, O=None, L=San Diego, ST=California, C=US" -a -g 2048 -o <host>.csr -d "sql:./"

        Then specify the content of file <host>.csr when prompted for a CSR upon purchasing a certificate from a signing authority.

        Copy the purchased certificate to a file named <host>.crt

        Import the certificate to the database
        certutil -A -n <host> -t "p,p,p" -i <host>.crt -d "sql:./"

        If necessary to use an intermediate certificate, it can be imported as such:
        certutil -A -n my_intermediate_certificate -t "p,p,p" -i intermediate.crt -d "sql:./"
        where "intermediate.crt" is the intermediate certificate file downloaded from the signing authority.

    6. Verify that the certificates exist in the database

      certutil -L -n <host> -d "sql:./"
      certutil -L -n my_intermediate_certificate -d "sql:./"

To use this certificate and create an HTTPS server, do the following:

// Initialize secure socket to use certificate database (note: replace `<dir>`
// with the absolute path to the certificate database directory, and `<password>`
// with the value chosen above)
SecureSocket.initialize(database: "<dir>", password: "<password>");

// Bind secure HTTP server to specified host and port (typically 443)
HttpServer.bindSecure("<host>", 443, certificateName: "<host>")
  .then((HttpServer httpServer) {

    // Listen for incoming requests
    httpServer.listen((HttpRequest httpRequest) {

      // TODO: process request
    });
  })
  .catchError((error) {

    // TODO: handle error
  });

Update

I don't have enough reputation points to respond to the comments, so here are additional details that may help answer the questions: Client certificates are not used to encrypt client-server communication and are not needed in the common scenario of establishing secure communication between a web browser and a webserver via HTTPS. The steps outlined above show how to create an HTTPS server in Dart using bindSecure.

Sign up to request clarification or add additional context in comments.

4 Comments

just to note, in your first paragraph about there being a known bug in dart on IE9, I believe dart only supports IE10+ so this isn't really a bug, just not supported
'Client certificates are used by servers to identify and authorize clients, which appears not to be the objective of this question.' - what I want to achieve is for all communications between client and server to be encrypted over https rather than plain http. Do I still need to do this procedure with the certificate database if I'm not interested in identifying and authorizing clients? or is that all a prerequisite to have coms over https?
thanks, for the update, so what would you do if you just wanted your server to only use https rather than http? or is this not an option? All I want is my server to only accept https in and respond with https out.
Calling HttpServer.bindSecure creates an HTTPS server (only). The server will not respond to HTTP requests unless HttpServer.bind is also called.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.