Hacker News new | past | comments | ask | show | jobs | submit login

I've never found a good, single document that covers self-signed certificates well. Googling for guidance results in a lot of different ways to do it, and if you don't find one that does exactly what you want, trying to combine that one with a different one that does the things missing from the first might not work because they are using different approaches.

I did manage to glean enough to make a pair of simple scripts that seemed to work for my needs, but have no idea if they are actually right, or if putting together things from different guides messed things up.

Here's the script I use for my root certificate (makeroot.sh):

  #!/bin/bash
  NAME=${1:?Must specify name for root}
  CN=${CN:-My Little Certificate Authority}
  O=${O:-My Home Network}
  C=${C:-US}
  DAYS=${DAYS:-365}
  PW=${PW:--aes256}
  SUBJ="/CN=$CN/O=$O/C=$C"
  openssl genrsa $PW -out $NAME.key 2048
  openssl req -x509 -new -subj "$SUBJ" -nodes -key $NAME.key -sha256 -days $DAYS -out $NAME.pem
So suppose I'm setting up a private certificate authority for my iot devices. I would do:

  $ ./makeroot.sh iot
That will make iot.key and iot.pem.

To make a certificate signed with the iot certificate I use this script (makecert.sh):

  #!/bin/bash
  NAME=${1:?Must specify name for cert}
  ROOT=${2:?Must specify name for root}
  CA="-CA $ROOT.pem -CAkey $ROOT.key -CAcreateserial"
  O=${O:-My Home Network}
  C=${C:-US}
  DAYS=${DAYS:-365}
  SUBJ="/CN=$NAME/O=$O/C=$C"
  openssl genrsa -out $NAME.key 2048
  openssl req -new -key $NAME.key -subj "$SUBJ" -out $NAME.csr
  openssl x509 -req -in $NAME.csr $CA -out $NAME.crt -days $DAYS -sha256
  rm $NAME.csr
 
E.g., to make a key for an iot doorbell:

  $ ./makecert.sh doorbell iot
That makes doorbell.crt and doorbell.key.

That worked well until the need arose to make an SNI certificate. I had expected that it would just be a matter of slightly tweaking makecert.sh, add a few more arguments.

But all I could find in the way of examples took a different approach, where most of the information is passed in a config file, and some of the guides I read indicated that you cannot pass the names on the command line to openssl when doing SNI. Anyway, this is the script I came up with (makesni.sh):

  #!/bin/bash
  function makeconf {
      CN=$1
      DIR='$dir'
      shift
      cat > tmp.conf <<HERE
  [ req ]
  distinguished_name = dn
  req_extensions = req_ext
  unique_subject  = no
  prompt = no
  
  [ ca ]
  default_ca = tzs_ca
  
  [ tzs_ca ]
  dir = ca-files
  private_key	= $DIR/iot.key
  certificate     = $DIR/iot.pem
  new_certs_dir   = $DIR
  database	= $DIR/index.txt	# database index file.
  unique_subject  = no
  default_md	= sha256		# use public key default MD
  serial		= $DIR/iot.srl 		# The current serial number
  email_in_dn     = tzs@mouse-potato.com
  default_days    = 365
  
   
  [ dn ]
  CN = $CN
  O = My Home Network
  C = US
  
  [ policy_anything ]
  countryName		= optional
  stateOrProvinceName	= optional
  localityName		= optional
  organizationName	= optional
  organizationalUnitName	= optional
  commonName		= supplied
  emailAddress		= optional
  
  [req_ext]
  HERE
  
      if [ -n "$1" ]
      then
          cat >> tmp.conf <<HERE
  subjectAltName = @alts
  
  [ alts ]
  DNS.1 = $1
  HERE
          shift
      fi
      POS=2
      while [ -n "$1" ]
      do
          echo "DNS.$POS = $1" >> tmp.conf
          shift
          POS=$((POS + 1))
      done
  }
  
  NAME=${1:?Must specify name for cert}
  makeconf $*
  openssl genrsa -out out/$NAME.key 2048
  openssl req -new -key out/$NAME.key -config tmp.conf -out out/$NAME.csr
  openssl ca -policy policy_anything -out out/$NAME.crt -config tmp.conf -extensions  req_ext -infiles out/$NAME.csr
  rm out/$NAME.csr tmp.conf
  
This assumes a directory, ca_files, that contains iot.key and iot.pem, and also an empty file named index.txt. Also it assumes in out directory.

To make an SNI certificate for a device that has three hosts, named fridge, freezer, and icemaker:

  $ ./makesni.sh fridge freezer icemaker
That will make fridge.crt and fridge.key in the out directory, and that will have fridge as the CN and freezer and icemaker as subject alternate names.

OK, so now I can put doorbell.crt and doorbell.key on the doorbell device, and fridge.crt and fridge.key on the device that has the fridge, freezer, and icemaker sites, and all is well, right?

Well...I also need to give my browsers iot.pem so they will recognize those other certificates. I'd also like curl and Perl and Python to recognize them, so that I can write scripts that do fancy iot things.

I didn't find any good guide to installing the CA certificate. From a bunch of Googling I came up with:

• On Debian Linux, copy iot.pem to /usr/local/share/ca-certificates, and change the extension to .crt.

Run update-ca-certificates.

That should make it available to Perl, Python, and curl.

For Chrome and Firefox, find their certificate management dialogs and use them to add the certificate.

• On OS X, double-click iot.pem. That should open Keychain Access. Let it import the certificate. Set it to be trusted for SSL. That will make it work in Chrome and Safari.

For Firefox, same as Linux.

For Perl, do one of:

1. Set environment variable PERL_LWP_SSL_CA_PATH or HTTPS_CA_DIR to point to a directory containing iot.pem, or

2. Set the environment variable PERL_LWP_SSL_CA_FILE of HTTPS_CA_FILE to point to iot.pem, or

The first requires that the directory contain symbolic links of the form hash.N where hash is a hash of the certificate and N is a sequence number. You need two of these, because there apparently is an old hash and a new hash. 'openssl x509 -subject_hash -noout -in iot.pem' to get the new hash, and 'openssl x509 -subject_hash_old -noout -in iot.pem' to get the old hash. Or just go to the cert directory and run 'c_rehash .' and 'c_rehash -old .' and those will make all the symlinks for you.

For Python3, similar to Perl but with SSL_CERT_DIR and SSL_CERT_FILE as the environment variable. Same hash symlinks as Perl (although I think you only need the new hash).

For curl, "--cacert iot.pem" or "--capath <dir>" where <dir> is a directory with the certificate. Same symlink considerations as Python3. Or set CURL_CA_BUNDLE env variable to point to a bundle that contains iot.pem. A bundle is just a bunch of certificate fills concatenated.

• Windows, I have no idea.




Not using dhparam? Dont like ECDH?

I wrote a similar amateur script years ago which has required updates from time to time to reflect new developments in the ongoing SSL saga.

This was started before anyone cared about SNI.

If the use case for the CA is a home network, I prefer using a local SSL-enabled proxy for connecting to both remote and local SSL-enabled endpoints. This lets me specify a short list of acceptable ciphers. It also permits me to use legacy, non SNI-enabled SSL/TLS clients. The remote and local hosts are "backends" that go in the proxy config file. I control DNS via local root or use HOSTS to redirect to the proxy.

If I was running multiple local SSL enabled devices/servers from the same local IP on a home network, then I believe I could just put these in the config file as backends listening on high, unprivileged ports. I do not believe I would need SNI because I could filter requests based on domain name and/or the filepath in the url.

The ultimate solution IMO would be an sslwrap type utility that has been revised to use more modern encryption, i.e. NaCl. Any application could then use NaCl instead of SSL/TLS, without having to modify the application. The NaCl author has menitoned several times that he has written such a utility and even said he will release it at some point.

IMO, that would be a big step in freeing us from the ills of SSL/TLS and the 3rd party CA system. Users would get easy-to-use, high quality, high speed cryptography without having to learn all of the SSL/TLS complexity, not to mention having to keep up with incessant bugs and security updates.


If you shed all legacy compatibility and narrow your configuration down to modern AEAD ciphersuites and an ECDH handshake, you can get TLS to a point asymptotically as secure as the best secure transport you'd achieve with NaCL and no other crypto primitives. Which leaves you to wonder why you'd bother doing the NaCL thing at all --- which is probably why not many people use custom secure transports.

Most (not all) of what's gone wrong with TLS has gone wrong in things that had already been outmoded for a very long time, and long since replaced with better constructions in later versions of the protocol.


One of the things that perplexes me as a naive user about TLS is the ridiculous number of cipher choices. How do you explain it? Some people still need them? Impossible/impractical to cut TLS down to size? People who comment intelligently about crypto seem to agree that complexity is the enemy of security, but does TLS even try to reduce complexity?

There is so much accumulated cruft to SSL/TLS and the implemented x509 certificate scheme that to me, as a noob who knows nothing about crypto i.e. the average user, the easier path is to scrap all that ("shed all legacy" junk) and focus on learning a few things that are both flexible and known to be useful. I believe NaCl fits this role.

I have some basic UNIX-like utilities built with NaCl, one for each function (crypto_box, crypto_secretbox, etc.). Minimal non-djb code. In the interests of experimentation and learning, I prefer using small, separate utilities versus applications that do multiple jobs.

I would be interested in an "expert" opinion on my experiments with these utilities but crypto is such a devisive topic. Though they may be initiated as sensible, honest questions, online discussions quickly turn toward dogma supporting status quo, mindless memes, subtle insults and are sometimes derailed into the realm of absurdity. I would post an example of the usage for comment, but I am not interested in being chastised by the HN peanut gallery. It is just intellectual experimentation, nothing more.

IMO, as a general principle not limited to crypto, there is nothing wrong with "custom" anything if it has passed the same QA tests as the "mass-produced" version. Sometimes in fact custom is higher quality than mass-produced. Popularity does not always signify higher quality. Perhaps nowhere is this more evident than in the world of software.

IMO, a "naclwrap" program would be very useful, even in a "TLS world". Like stunnel but for nacl. Whether "everyone" would use it is an interesting question but ultimately not something I care about.


There is no question that TLS is loaded up with cruft and dangerous legacy goo.

But, again, you can remove 80-90% of it if you don't care about compat. People run into a cognitive block when they think about TLS because they assume TLS means "browser compatible". But no browser speaks a NaCL transport today, so that's out the window.

Without the requirement to support browsers, you can:

* Allow only an ECDH handshake.

* Allow only the Chapoly ciphersuite, in TLS 1.2's AEAD format.

* Eliminate CAs and do an SSH-style key-continuity scheme.

This TLS "subprotocol" already exists and is already supported by most of the TLS libraries, all of which have been audited. It's supported by middleboxes and monitoring tools so it can be deployed operationally. Every mainstream programming language has bindings to it. Meanwhile, NaCL doesn't actually provide a transport protocol or even the security semantics of a secure transport; that's work you'll have to do de novo, and you will generate bugs doing it.

So what's the advantage to scrapping TLS and redoing it with NaCL?


I agree. Especially with the part about CAs and a more SSH-like approach.

But unlike you I have little interest in "browsers". This is why I would want a "naclwrap" utility but you might not see any point. CurveCP is the experimental transport protocol. I do not need it in a browser because I am not interested in browsers. I like experimenting outside of browsers and the "web" so I have no reason to resist CurveCP.

What is the advantage of scraping TLS? If you mean for everyone, maybe there is none. Why not allow both TLS and NaCl to coexist? Why does TLS have to be "redone" with NaCl?

For me personally, the advantage of "scraping TLS" is that I get to ignore all the cruft and complexity that I have to sift through to get to the proper "subprotocol" within TLS. Too much work.

I am not the one who will write "naclwrap" if it ever is released. The person who wrote it does not introduce bugs and security issues. He is not like the people who work on TLS and most developers in general. He is careful.

In any case, I am not tasked with persuading anyone else to scrap TLS. I am simply a user who 1. likes NaCl, 2. prefers the idea of per packet encryption to the notion of encrypted "tunnels" and 3. is apt to complain about TLS only because like other web users I am forced to use it whether I want to or not.

For someone focused on influencing developers who write programs for other people, shaping web standards or at least very interested in where they might be heading, your comments are poignant. But I am just a user. I write trivial programs for myself. I am not futilely trying to tell developers what to do, shape standards nor am I very interested in where things are heading, except to the extent I can minimize the computer usage-related annoyances I must endure.


Compared to NaCl, for someone who wants to learn how cryptography libraries work, "TLS" is too much of a moving target. It is unfinished software that may never be finished. Too many versions of too many libraries supporting too many ciphers by too many developers. Too many knobs and switches.

As for OpenSSL, not everyone is on 1.1 yet. There is no ChaCha20-Poly1305 in 1.0.1_. So while some bits of NaCl have been adopted into the TLS suite, it is only a subset of web servers that are supporting the so-called "subprotocol". And still no Ed25519, even though it has been used in OpenSSH for some time now.

All these factors make TLS undesirable for me. Too much complexity compared to NaCl, IMO. For others, TLS may be the right choice.


I do not believe I would need SNI because I could filter requests based on domain name and/or the filepath in the url.

The point of SNI is to send the domain name as part of the TLS handshake, because the URL is only sent after the secure connection is established (after the cert is sent).


The point of SNI, i.e. the reason for its existence, is to allow more than one SSL-enabled website to use the same shared IP address. Prior to SNI each SSL-enabled website required its own dedicated IP address. On a home network, is shortage of RFC1918 IP addresses really a problem?


You are talking about certificates with subject alternative names. SAN has nothing to do with SNI (server name identification).




Join us for AI Startup School this June 16-17 in San Francisco!

Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: