diff --git a/2016-03-21-elliptic-curve-certificate-authority.html b/2016-03-21-elliptic-curve-certificate-authority.html
new file mode 100644
index 0000000..c141183
--- /dev/null
+++ b/2016-03-21-elliptic-curve-certificate-authority.html
@@ -0,0 +1,291 @@
+
+
+
+
+
+
Notes from setting up a two-level (root and intermediate) CA using EC certs, combined from two decent sets of instructions here and here. This is the CliffsNotes version; see those two docs for more detail. XXXX is used as a placeholder here; search for it and replace.
+
+Create directory structure
+
+mkdir ca
+cd ca
+mkdir -p {root,intermediate}/{certs,crl,csr,newcerts,private}
+mkdir -p {client,server}/{certs,csr,pfx,private}
+touch {root,intermediate}/database
+echo 1000 | tee {root,intermediate}/{serial,crlnumber}
+chmod 700 {root,intermediate,client,server}/private
+Create openssl.cnf
+cat > openssl.cnf <<'END'
+[ ca ]
+default_ca = ca_intermediate
+
+[ ca_root ]
+dir = root
+certs = $dir/certs
+crl_dir = $dir/crl
+new_certs_dir = $dir/newcerts
+database = $dir/database
+serial = $dir/serial
+crlnumber = $dir/crlnumber
+private_key = $dir/private/root.key.pem
+certificate = $dir/certs/root.cert.pem
+crl = $dir/crl/root.crl.pem
+crl_extensions = ext_crl
+default_md = sha256
+name_opt = ca_default
+cert_opt = ca_default
+default_crl_days = 30
+default_days = 3650
+preserve = no
+policy = policy_strict
+
+[ ca_intermediate ]
+dir = intermediate
+certs = $dir/certs
+crl_dir = $dir/crl
+new_certs_dir = $dir/newcerts
+database = $dir/database
+serial = $dir/serial
+crlnumber = $dir/crlnumber
+private_key = $dir/private/intermediate.key.pem
+certificate = $dir/certs/intermediate.cert.pem
+crl = $dir/crl/intermediate.crl.pem
+crl_extensions = ext_crl
+default_md = sha256
+name_opt = ca_default
+cert_opt = ca_default
+default_crl_days = 30
+default_days = 375
+preserve = no
+policy = policy_loose
+
+[ policy_strict ]
+countryName = match
+stateOrProvinceName = match
+organizationName = match
+organizationalUnitName = optional
+commonName = supplied
+emailAddress = optional
+
+[ policy_loose ]
+countryName = optional
+stateOrProvinceName = optional
+localityName = optional
+organizationName = optional
+organizationalUnitName = optional
+commonName = supplied
+emailAddress = optional
+
+[ req ]
+default_bits = 2048
+string_mask = utf8only
+default_md = sha256
+distinguished_name = req_distinguished_name
+
+[ req_distinguished_name ]
+countryName = Country Name (2 letter code)
+stateOrProvinceName = State or Province Name
+localityName = Locality Name
+0.organizationName = Organization Name
+organizationalUnitName = Organizational Unit Name
+commonName = Common Name
+emailAddress = Email Address
+
+[ ext_root ]
+subjectKeyIdentifier = hash
+authorityKeyIdentifier = keyid:always, issuer
+basicConstraints = critical, CA:true
+keyUsage = critical, digitalSignature, cRLSign, keyCertSign
+
+[ ext_intermediate ]
+subjectKeyIdentifier = hash
+authorityKeyIdentifier = keyid:always, issuer
+basicConstraints = critical, CA:true, pathlen:0
+keyUsage = critical, digitalSignature, cRLSign, keyCertSign
+
+[ ext_client ]
+basicConstraints = CA:FALSE
+nsCertType = client, email
+nsComment = "OpenSSL Generated Client Certificate"
+subjectKeyIdentifier = hash
+authorityKeyIdentifier = keyid, issuer
+keyUsage = critical, nonRepudiation, digitalSignature, keyEncipherment
+extendedKeyUsage = clientAuth, emailProtection
+
+[ ext_server ]
+basicConstraints = CA:FALSE
+nsCertType = server
+nsComment = "OpenSSL Generated Server Certificate"
+subjectKeyIdentifier = hash
+authorityKeyIdentifier = keyid, issuer:always
+keyUsage = critical, digitalSignature, keyEncipherment
+extendedKeyUsage = serverAuth
+
+[ ext_crl ]
+authorityKeyIdentifier = keyid:always
+
+[ ext_ocsp ]
+basicConstraints = CA:FALSE
+subjectKeyIdentifier = hash
+authorityKeyIdentifier = keyid, issuer
+keyUsage = critical, digitalSignature
+extendedKeyUsage = critical, OCSPSigning
+END
+
+
+Create a root key
+
+openssl ecparam -name secp384r1 -genkey | openssl ec -aes-256-cbc -out root/private/root.key.pem
+# Create strong root key password
+chmod 400 root/private/root.key.pem
+
+
+Create a self-signed root cert
+
+openssl req -config openssl.cnf -key root/private/root.key.pem -new -extensions ext_root -out root/certs/root.cert.pem -x509 -subj '/C=US/ST=California/O=XXXX/OU=XXXX Certificate Authority/CN=XXXX Root CA' -days 7300
+# Enter root key password
+chmod 444 root/certs/root.cert.pem
+
+
+Verify root cert
+
+openssl x509 -noout -text -in root/certs/root.cert.pem
+
+
+Check:
+
+
+- Expiration date (20 years in future)
+- Signature algorithm (ecdsa-with-SHA256)
+- Public key size (384 bit)
+- CA:TRUE
+
+
+Create an intermediate key
+
+openssl ecparam -name secp384r1 -genkey | openssl ec -aes-256-cbc -out intermediate/private/intermediate.key.pem
+# Create strong intermediate key password
+chmod 400 intermediate/private/intermediate.key.pem
+
+
+Create an intermediate certificate signing request (CSR)
+
+openssl req -config openssl.cnf -new -key intermediate/private/intermediate.key.pem -out intermediate/csr/intermediate.csr.pem -subj '/C=US/ST=California/O=XXXX/OU=XXXX Certificate Authority/CN=XXXX Intermediate'
+# Enter intermediate key password
+
+
+Sign intermediate cert with root key
+
+openssl ca -config openssl.cnf -name ca_root -extensions ext_intermediate -notext -in intermediate/csr/intermediate.csr.pem -out intermediate/certs/intermediate.cert.pem
+# Enter root key password
+chmod 444 intermediate/certs/intermediate.cert.pem
+
+
+Verify intermediate cert
+
+openssl x509 -noout -text -in intermediate/certs/intermediate.cert.pem
+openssl verify -CAfile root/certs/root.cert.pem intermediate/certs/intermediate.cert.pem
+
+
+Check:
+
+
+- Expiration date (10 years in future)
+- Signature algorithm (ecdsa-with-SHA256)
+- Public key size (384 bit)
+- CA:TRUE
+- OK
+
+
+Create a chain certificate file
+
+cat intermediate/certs/intermediate.cert.pem root/certs/root.cert.pem > intermediate/certs/chain.cert.pem
+chmod 444 intermediate/certs/chain.cert.pem
+
+
+Create a client key
+
+You can substitute “server” for “client” for a server cert.
+
+openssl ecparam -name secp384r1 -genkey | openssl ec -aes-256-cbc -out client/private/test1.key.pem
+# Create client key password
+chmod 400 client/private/test1.key.pem
+
+
+Create a client certificate signing request (CSR)
+
+openssl req -config openssl.cnf -new -key client/private/test1.key.pem -out client/csr/test1.csr.pem -subj '/C=US/ST=California/O=XXXX/OU=XXXX Test/CN=XXXX Test 1'
+
+
+Sign client cert with intermediate key
+
+openssl ca -config openssl.cnf -extensions ext_client -notext -in client/csr/test1.csr.pem -out client/certs/test1.cert.pem
+# Enter intermediate key password
+chmod 444 client/certs/test1.cert.pem
+
+
+Verify client cert
+
+openssl x509 -noout -text -in client/certs/test1.cert.pem
+openssl verify -CAfile intermediate/certs/chain.cert.pem client/certs/test1.cert.pem
+
+
+Check:
+
+
+- Expiration date (1 year in future)
+- Signature algorithm (ecdsa-with-SHA256)
+- Public key size (384 bit)
+- CA:FALSE
+- OK
+
+
+Create a PKCS#12 bundle for the client
+
+This is an easy(er) way to get all the necessary keys & certs to the client in one package.
+
+openssl pkcs12 -export -out client/pfx/test1.pfx -inkey client/private/test1.key.pem -in client/certs/test1.cert.pem -certfile intermediate/certs/chain.cert.pem
+# Enter both the client key password, and a new password for the export; you'll need to give the latter to the client
+
+
+Generate a certificate revocation list (CRL)
+
+Initially empty. You can also do this for your root CA.
+
+openssl ca -config openssl.cnf -gencrl -out intermediate/crl/intermediate.crl.pem
+
+
+Verify certificate revocation list
+
+openssl crl -in intermediate/crl/intermediate.crl.pem -noout -text
+
+
+Check:
+
+
+- Expiration date (30 days in future)
+- Signature algorithm (ecdsa-with-SHA256)
+
+
+Revoke a certificate
+
+Only do this if you need to. Find the certificate:
+
+cat intermediate/database
+# You'll need the hex-formatted serial number, in the third field.
+# Substitute serial number for YYYY below.
+
+
+Revoke it:
+
+openssl ca -config openssl.cnf -revoke intermediate/newcerts/YYYY.pem
+# Enter intermediate key password
+
+
+Generate a new CRL file:
+
+openssl ca -config openssl.cnf -gencrl -out intermediate/crl/intermediate.crl.pem
+# Enter intermediate key password
+
+
+
diff --git a/2016-03-26-nitrokey-hsm-ec-setup.html b/2016-03-26-nitrokey-hsm-ec-setup.html
new file mode 100644
index 0000000..e31105d
--- /dev/null
+++ b/2016-03-26-nitrokey-hsm-ec-setup.html
@@ -0,0 +1,105 @@
+
+
+
+
+
+Following up from my previous writeup on creating an EC CA, let’s talk about key security.
+
+Hardware security modules are physical devices that manage keys. Generally, the rule is that they let you use the keys for operations (e.g. signing) given correct authentication, but don’t let you extract the raw key material. This means that if you’re holding the HSM, you know that no one else is currently abusing your key (though they may have done so in the past).
+
+Searching for reasonably-priced options, I found the Nitrokey HSM. Open source hardware, firmware, and software. Supports EC keys. Supports lots of keys. Supports Linux. Awesome.
+
+Open source gets a bad rap sometimes, for the same reason PHP does: it has a low barrier to entry (that’s a simplification in pretty much all directions, but roll with it). That means there’s a lot of crap out there, because it’s so easy to start things without a significant audience and not hold to rigorous standards. Open source hardware, however, doesn’t have this excuse. You’re selling it. The fact that you publish the designs and the firmware is secondary; you’re still making money from it, and there’s no excuse for shipping shit that you haven’t actually finished turning into a product.
+
+Below are the steps to get the Nitrokey HSM to a working state where it can generate an EC key pair, and (self-)sign a cert with it. Hopefully many of these go away in the future, as support percolates into release versions and distribution packages.
+
+Hardware & setup
+
+These instructions were developed and tested on a Raspberry Pi. Base setup instructions are here. You’ll also need a Nitrokey HSM, obviously.
+
+Install prerequisites
+
+sudo apt-get install pcscd libpcsclite-dev libssl-dev libreadline-dev autoconf automake build-essential docbook-xsl xsltproc libtool pkg-config git
+
+
+libccid
+
+You’ll need a newer version of libccid than currently exists in Raspbian Jessie (1.4.22 > 1.4.18). You can download it for your platform here, or use the commands below for an RPi.
+
+wget http://http.us.debian.org/debian/pool/main/c/ccid/libccid_1.4.22-1_armhf.deb
+sudo dpkg -i libccid_1.4.22-1_armhf.deb
+
+
+Install libp11
+
+engine_pkcs11 requires >= 0.3.1. Raspbian Jessie has 0.2.8. Debian sid has a package, but you need the dev package as well, so you might as well build it.
+
+git clone https://github.com/OpenSC/libp11.git
+cd libp11
+./bootstrap
+./configure
+make
+sudo make install
+cd ..
+
+
+Install engine_pkcs11
+
+EC requires engine_pkcs11 >= 0.2.0. Raspbian Jessie has 0.1.8. Debian sid also has a package that I haven’t tested.
+
+git clone https://github.com/OpenSC/engine_pkcs11.git
+cd engine_pkcs11
+./bootstrap
+./configure
+make
+sudo make install
+cd ..
+
+
+Install OpenSC
+
+As of writing (2016/Mar/26), working support for the Nitrokey HSM requires a build of OpenSC that hasn’t made it into a package yet (0.16.0). They’ve also screwed up their repository branching, so master is behind the release branch and won’t work.
+
+git clone — branch opensc-0.16.0 https://github.com/OpenSC/OpenSC.git
+cd OpenSC
+./bootstrap
+./configure
+make
+sudo make install
+cd ..
+
+
+Misc
+
+sudo ldconfig
+
+
+Initialize the device
+
+/usr/local/bin/sc-hsm-tool --initialize
+
+
+If this tells you that it can’t find the device, you probably forgot to update libccid, and need to start over. You’ll need to set an SO PIN and PIN the first time. The SO PIN should be 16 characters, and the PIN 6. Both should be all digits. They can technically be hex, but some apps get confused if they see letters.
+
+Generate a test EC key pair
+
+/usr/local/bin/pkcs11-tool --module /usr/local/lib/opensc-pkcs11.so---login --keypairgen --key-type EC:prime256v1 --label test
+
+
+Generate a self-signed cert
+
+openssl
+OpenSSL> engine -t -pre SO_PATH:/usr/lib/arm-linux-gnueabihf/openssl-1.0.0/engines/libpkcs11.so -pre ID:pkcs11 -pre LIST_ADD:1 -pre LOAD -pre MODULE_PATH:/usr/local/lib/pkcs11/opensc-pkcs11.so dynamic
+...
+OpenSSL> req -engine pkcs11 -new -keyform engine -out cert.pem -text -x509 -days 3640 -key label_test -subj '/CN=test'
+
+
+If you now have a cert.pem file, you’re golden. If you see “error in req”, you probably have a bad version of OpenSC.
+
+Now, delete the file, re-initialize the device, and you’re good to go.
+
+More instructions on various Nitrokey HSM operations can be found here.
+
+Instructions for running a complete certificate authority (CA) with your Nitrokey are here.
+
+
diff --git a/2016-03-27-ec-ca-redux-now-with-more-nitrokey.html b/2016-03-27-ec-ca-redux-now-with-more-nitrokey.html
index 8ec1303..7a4d5cd 100644
--- a/2016-03-27-ec-ca-redux-now-with-more-nitrokey.html
+++ b/2016-03-27-ec-ca-redux-now-with-more-nitrokey.html
@@ -1,5 +1,5 @@
-
+
diff --git a/2019-04-14-reboot.html b/2019-04-14-reboot.html
index 7f63d03..e25c485 100644
--- a/2019-04-14-reboot.html
+++ b/2019-04-14-reboot.html
@@ -5,6 +5,6 @@
Previous generations of "where the flamingcow roams" have existed on Blogger and Medium, but have been dormant for some time. Tired of my posts there being "decorated" by the hosting provider without approval and inspired by Fabien Sanglard, I'm rebooting here.
-Posts prior to this one are copied from Blogger or Medium. Forgive me for all their historical naiveté. Posts after this are new here, and I'm sure will look equally silly in ten years.
+Posts prior to this one are copied from Blogger or Medium. Forgive me for all their historical naiveté. Posts after this are new here, and I'm sure will look equally silly in ten years. The historical posts have been hand-translated to markdown and likely contain translation errors.
diff --git a/include/top.html b/include/top.html
index 149b7f0..764e1f0 100644
--- a/include/top.html
+++ b/include/top.html
@@ -12,7 +12,7 @@
-
+">
diff --git a/index.html b/index.html
index ea8ec4c..637e00d 100644
--- a/index.html
+++ b/index.html
@@ -1,12 +1,14 @@
+
+
-
diff --git a/markdown/2016-03-21-elliptic-curve-certificate-authority.md b/markdown/2016-03-21-elliptic-curve-certificate-authority.md
new file mode 100644
index 0000000..5482024
--- /dev/null
+++ b/markdown/2016-03-21-elliptic-curve-certificate-authority.md
@@ -0,0 +1,264 @@
+
+
+
+
+
+Notes from setting up a two-level (root and intermediate) CA using EC certs, combined from two decent sets of instructions [here](https://jamielinux.com/docs/openssl-certificate-authority/introduction.html) and [here](https://wiki.openssl.org/index.php/Command_Line_Elliptic_Curve_Operations). This is the CliffsNotes version; see those two docs for more detail. XXXX is used as a placeholder here; search for it and replace.
+
+### Create directory structure
+
+ mkdir ca
+ cd ca
+ mkdir -p {root,intermediate}/{certs,crl,csr,newcerts,private}
+ mkdir -p {client,server}/{certs,csr,pfx,private}
+ touch {root,intermediate}/database
+ echo 1000 | tee {root,intermediate}/{serial,crlnumber}
+ chmod 700 {root,intermediate,client,server}/private
+ Create openssl.cnf
+ cat > openssl.cnf <<'END'
+ [ ca ]
+ default_ca = ca_intermediate
+
+ [ ca_root ]
+ dir = root
+ certs = $dir/certs
+ crl_dir = $dir/crl
+ new_certs_dir = $dir/newcerts
+ database = $dir/database
+ serial = $dir/serial
+ crlnumber = $dir/crlnumber
+ private_key = $dir/private/root.key.pem
+ certificate = $dir/certs/root.cert.pem
+ crl = $dir/crl/root.crl.pem
+ crl_extensions = ext_crl
+ default_md = sha256
+ name_opt = ca_default
+ cert_opt = ca_default
+ default_crl_days = 30
+ default_days = 3650
+ preserve = no
+ policy = policy_strict
+
+ [ ca_intermediate ]
+ dir = intermediate
+ certs = $dir/certs
+ crl_dir = $dir/crl
+ new_certs_dir = $dir/newcerts
+ database = $dir/database
+ serial = $dir/serial
+ crlnumber = $dir/crlnumber
+ private_key = $dir/private/intermediate.key.pem
+ certificate = $dir/certs/intermediate.cert.pem
+ crl = $dir/crl/intermediate.crl.pem
+ crl_extensions = ext_crl
+ default_md = sha256
+ name_opt = ca_default
+ cert_opt = ca_default
+ default_crl_days = 30
+ default_days = 375
+ preserve = no
+ policy = policy_loose
+
+ [ policy_strict ]
+ countryName = match
+ stateOrProvinceName = match
+ organizationName = match
+ organizationalUnitName = optional
+ commonName = supplied
+ emailAddress = optional
+
+ [ policy_loose ]
+ countryName = optional
+ stateOrProvinceName = optional
+ localityName = optional
+ organizationName = optional
+ organizationalUnitName = optional
+ commonName = supplied
+ emailAddress = optional
+
+ [ req ]
+ default_bits = 2048
+ string_mask = utf8only
+ default_md = sha256
+ distinguished_name = req_distinguished_name
+
+ [ req_distinguished_name ]
+ countryName = Country Name (2 letter code)
+ stateOrProvinceName = State or Province Name
+ localityName = Locality Name
+ 0.organizationName = Organization Name
+ organizationalUnitName = Organizational Unit Name
+ commonName = Common Name
+ emailAddress = Email Address
+
+ [ ext_root ]
+ subjectKeyIdentifier = hash
+ authorityKeyIdentifier = keyid:always, issuer
+ basicConstraints = critical, CA:true
+ keyUsage = critical, digitalSignature, cRLSign, keyCertSign
+
+ [ ext_intermediate ]
+ subjectKeyIdentifier = hash
+ authorityKeyIdentifier = keyid:always, issuer
+ basicConstraints = critical, CA:true, pathlen:0
+ keyUsage = critical, digitalSignature, cRLSign, keyCertSign
+
+ [ ext_client ]
+ basicConstraints = CA:FALSE
+ nsCertType = client, email
+ nsComment = "OpenSSL Generated Client Certificate"
+ subjectKeyIdentifier = hash
+ authorityKeyIdentifier = keyid, issuer
+ keyUsage = critical, nonRepudiation, digitalSignature, keyEncipherment
+ extendedKeyUsage = clientAuth, emailProtection
+
+ [ ext_server ]
+ basicConstraints = CA:FALSE
+ nsCertType = server
+ nsComment = "OpenSSL Generated Server Certificate"
+ subjectKeyIdentifier = hash
+ authorityKeyIdentifier = keyid, issuer:always
+ keyUsage = critical, digitalSignature, keyEncipherment
+ extendedKeyUsage = serverAuth
+
+ [ ext_crl ]
+ authorityKeyIdentifier = keyid:always
+
+ [ ext_ocsp ]
+ basicConstraints = CA:FALSE
+ subjectKeyIdentifier = hash
+ authorityKeyIdentifier = keyid, issuer
+ keyUsage = critical, digitalSignature
+ extendedKeyUsage = critical, OCSPSigning
+ END
+
+### Create a root key
+
+ openssl ecparam -name secp384r1 -genkey | openssl ec -aes-256-cbc -out root/private/root.key.pem
+ # Create strong root key password
+ chmod 400 root/private/root.key.pem
+
+### Create a self-signed root cert
+
+ openssl req -config openssl.cnf -key root/private/root.key.pem -new -extensions ext_root -out root/certs/root.cert.pem -x509 -subj '/C=US/ST=California/O=XXXX/OU=XXXX Certificate Authority/CN=XXXX Root CA' -days 7300
+ # Enter root key password
+ chmod 444 root/certs/root.cert.pem
+
+### Verify root cert
+
+ openssl x509 -noout -text -in root/certs/root.cert.pem
+
+Check:
+
+* Expiration date (20 years in future)
+* Signature algorithm (ecdsa-with-SHA256)
+* Public key size (384 bit)
+* CA:TRUE
+
+### Create an intermediate key
+
+ openssl ecparam -name secp384r1 -genkey | openssl ec -aes-256-cbc -out intermediate/private/intermediate.key.pem
+ # Create strong intermediate key password
+ chmod 400 intermediate/private/intermediate.key.pem
+
+### Create an intermediate certificate signing request (CSR)
+
+ openssl req -config openssl.cnf -new -key intermediate/private/intermediate.key.pem -out intermediate/csr/intermediate.csr.pem -subj '/C=US/ST=California/O=XXXX/OU=XXXX Certificate Authority/CN=XXXX Intermediate'
+ # Enter intermediate key password
+
+### Sign intermediate cert with root key
+
+ openssl ca -config openssl.cnf -name ca_root -extensions ext_intermediate -notext -in intermediate/csr/intermediate.csr.pem -out intermediate/certs/intermediate.cert.pem
+ # Enter root key password
+ chmod 444 intermediate/certs/intermediate.cert.pem
+
+### Verify intermediate cert
+
+ openssl x509 -noout -text -in intermediate/certs/intermediate.cert.pem
+ openssl verify -CAfile root/certs/root.cert.pem intermediate/certs/intermediate.cert.pem
+
+Check:
+
+* Expiration date (10 years in future)
+* Signature algorithm (ecdsa-with-SHA256)
+* Public key size (384 bit)
+* CA:TRUE
+* OK
+
+### Create a chain certificate file
+
+ cat intermediate/certs/intermediate.cert.pem root/certs/root.cert.pem > intermediate/certs/chain.cert.pem
+ chmod 444 intermediate/certs/chain.cert.pem
+
+### Create a client key
+
+You can substitute “server” for “client” for a server cert.
+
+ openssl ecparam -name secp384r1 -genkey | openssl ec -aes-256-cbc -out client/private/test1.key.pem
+ # Create client key password
+ chmod 400 client/private/test1.key.pem
+
+### Create a client certificate signing request (CSR)
+
+ openssl req -config openssl.cnf -new -key client/private/test1.key.pem -out client/csr/test1.csr.pem -subj '/C=US/ST=California/O=XXXX/OU=XXXX Test/CN=XXXX Test 1'
+
+### Sign client cert with intermediate key
+
+ openssl ca -config openssl.cnf -extensions ext_client -notext -in client/csr/test1.csr.pem -out client/certs/test1.cert.pem
+ # Enter intermediate key password
+ chmod 444 client/certs/test1.cert.pem
+
+### Verify client cert
+
+ openssl x509 -noout -text -in client/certs/test1.cert.pem
+ openssl verify -CAfile intermediate/certs/chain.cert.pem client/certs/test1.cert.pem
+
+Check:
+
+* Expiration date (1 year in future)
+* Signature algorithm (ecdsa-with-SHA256)
+* Public key size (384 bit)
+* CA:FALSE
+* OK
+
+### Create a PKCS#12 bundle for the client
+
+This is an easy(er) way to get all the necessary keys & certs to the client in one package.
+
+ openssl pkcs12 -export -out client/pfx/test1.pfx -inkey client/private/test1.key.pem -in client/certs/test1.cert.pem -certfile intermediate/certs/chain.cert.pem
+ # Enter both the client key password, and a new password for the export; you'll need to give the latter to the client
+
+### Generate a certificate revocation list (CRL)
+
+Initially empty. You can also do this for your root CA.
+
+ openssl ca -config openssl.cnf -gencrl -out intermediate/crl/intermediate.crl.pem
+
+### Verify certificate revocation list
+
+ openssl crl -in intermediate/crl/intermediate.crl.pem -noout -text
+
+Check:
+
+* Expiration date (30 days in future)
+* Signature algorithm (ecdsa-with-SHA256)
+
+### Revoke a certificate
+
+Only do this if you need to. Find the certificate:
+
+ cat intermediate/database
+ # You'll need the hex-formatted serial number, in the third field.
+ # Substitute serial number for YYYY below.
+
+Revoke it:
+
+ openssl ca -config openssl.cnf -revoke intermediate/newcerts/YYYY.pem
+ # Enter intermediate key password
+
+Generate a new CRL file:
+
+ openssl ca -config openssl.cnf -gencrl -out intermediate/crl/intermediate.crl.pem
+ # Enter intermediate key password
+
+
diff --git a/markdown/2016-03-26-nitrokey-hsm-ec-setup.md b/markdown/2016-03-26-nitrokey-hsm-ec-setup.md
new file mode 100644
index 0000000..6084678
--- /dev/null
+++ b/markdown/2016-03-26-nitrokey-hsm-ec-setup.md
@@ -0,0 +1,96 @@
+
+
+
+
+
+Following up from my previous writeup on [creating an EC CA](https://medium.com/where-the-flamingcow-roams/elliptic-curve-certificate-authority-bbdb9c3855f7#.wv19mvxse), let’s talk about key security.
+
+[Hardware security modules](https://en.wikipedia.org/wiki/Hardware_security_module) are physical devices that manage keys. Generally, the rule is that they let you use the keys for operations (e.g. signing) given correct authentication, but don’t let you extract the raw key material. This means that if you’re holding the HSM, you know that no one else is currently abusing your key (though they may have done so in the past).
+
+Searching for reasonably-priced options, I found the [Nitrokey HSM](https://shop.nitrokey.com/shop/product/nitrokey-hsm-7). Open source hardware, firmware, and software. Supports EC keys. Supports lots of keys. Supports Linux. Awesome.
+
+Open source gets a bad rap sometimes, for the same reason PHP does: it has a low barrier to entry (that’s a simplification in pretty much all directions, but roll with it). That means there’s a lot of crap out there, because it’s so easy to start things without a significant audience and not hold to rigorous standards. Open source hardware, however, doesn’t have this excuse. You’re selling it. The fact that you publish the designs and the firmware is secondary; you’re still making money from it, and there’s no excuse for shipping shit that you haven’t actually finished turning into a product.
+
+Below are the steps to get the Nitrokey HSM to a working state where it can generate an EC key pair, and (self-)sign a cert with it. Hopefully many of these go away in the future, as support percolates into release versions and distribution packages.
+
+### Hardware & setup
+
+These instructions were developed and tested on a Raspberry Pi. Base setup instructions are here. You’ll also need a Nitrokey HSM, obviously.
+
+### Install prerequisites
+
+ sudo apt-get install pcscd libpcsclite-dev libssl-dev libreadline-dev autoconf automake build-essential docbook-xsl xsltproc libtool pkg-config git
+
+### libccid
+
+You’ll need a [newer version of libccid](https://www.nitrokey.com/documentation/frequently-asked-questions#which-gnupg,-opensc-and-libccid-versions-are-required) than currently exists in Raspbian Jessie (1.4.22 > 1.4.18). You can download it for your platform here, or use the commands below for an RPi.
+
+ wget http://http.us.debian.org/debian/pool/main/c/ccid/libccid_1.4.22-1_armhf.deb
+ sudo dpkg -i libccid_1.4.22-1_armhf.deb
+
+### Install libp11
+
+engine\_pkcs11 requires >= 0.3.1. Raspbian Jessie has 0.2.8. Debian sid [has a package](https://packages.debian.org/sid/libp11-2), but you need the dev package as well, so you might as well build it.
+
+ git clone https://github.com/OpenSC/libp11.git
+ cd libp11
+ ./bootstrap
+ ./configure
+ make
+ sudo make install
+ cd ..
+
+### Install engine\_pkcs11
+
+EC [requires engine\_pkcs11 >= 0.2.0](https://www.nitrokey.com/forum/viewtopic.php?t=1549). Raspbian Jessie has 0.1.8. Debian [sid also has a package](https://packages.debian.org/sid/libengine-pkcs11-openssl) that I haven’t tested.
+
+ git clone https://github.com/OpenSC/engine_pkcs11.git
+ cd engine_pkcs11
+ ./bootstrap
+ ./configure
+ make
+ sudo make install
+ cd ..
+
+### Install OpenSC
+
+As of writing (2016/Mar/26), working support for the Nitrokey HSM [requires a build of OpenSC](https://www.nitrokey.com/documentation/frequently-asked-questions#which-gnupg,-opensc-and-libccid-versions-are-required) that hasn’t made it into a package yet (0.16.0). They’ve also screwed up their repository branching, so master is behind the release branch and won’t work.
+
+ git clone — branch opensc-0.16.0 https://github.com/OpenSC/OpenSC.git
+ cd OpenSC
+ ./bootstrap
+ ./configure
+ make
+ sudo make install
+ cd ..
+
+### Misc
+
+ sudo ldconfig
+
+### Initialize the device
+
+ /usr/local/bin/sc-hsm-tool --initialize
+
+If this tells you that it can’t find the device, you probably forgot to update libccid, and need to start over. You’ll need to set an SO PIN and PIN the first time. The SO PIN should be 16 characters, and the PIN 6. Both should be all digits. They can technically be hex, but some apps get confused if they see letters.
+
+### Generate a test EC key pair
+
+ /usr/local/bin/pkcs11-tool --module /usr/local/lib/opensc-pkcs11.so---login --keypairgen --key-type EC:prime256v1 --label test
+
+### Generate a self-signed cert
+
+ openssl
+ OpenSSL> engine -t -pre SO_PATH:/usr/lib/arm-linux-gnueabihf/openssl-1.0.0/engines/libpkcs11.so -pre ID:pkcs11 -pre LIST_ADD:1 -pre LOAD -pre MODULE_PATH:/usr/local/lib/pkcs11/opensc-pkcs11.so dynamic
+ ...
+ OpenSSL> req -engine pkcs11 -new -keyform engine -out cert.pem -text -x509 -days 3640 -key label_test -subj '/CN=test'
+
+If you now have a cert.pem file, you’re golden. If you see “error in req”, you probably have a [bad version of OpenSC](https://www.nitrokey.com/forum/viewtopic.php?t=1549).
+
+Now, delete the file, re-initialize the device, and you’re good to go.
+
+More instructions on various Nitrokey HSM operations can be found [here](https://github.com/OpenSC/OpenSC/wiki/SmartCardHSM#init).
+
+Instructions for running a complete certificate authority (CA) with your Nitrokey are [here](https://medium.com/where-the-flamingcow-roams/ec-ca-redux-now-with-more-nitrokey-729061e1b7c9#.d7igz5dhv).
+
+
diff --git a/markdown/2016-03-27-ec-ca-redux-now-with-more-nitrokey.md b/markdown/2016-03-27-ec-ca-redux-now-with-more-nitrokey.md
index a42a97c..8b040e6 100644
--- a/markdown/2016-03-27-ec-ca-redux-now-with-more-nitrokey.md
+++ b/markdown/2016-03-27-ec-ca-redux-now-with-more-nitrokey.md
@@ -1,5 +1,5 @@
-
+
diff --git a/markdown/2019-04-14-reboot.md b/markdown/2019-04-14-reboot.md
index 1fdfd59..cf0eea9 100644
--- a/markdown/2019-04-14-reboot.md
+++ b/markdown/2019-04-14-reboot.md
@@ -5,6 +5,6 @@
Previous generations of "where the flamingcow roams" have existed on Blogger and Medium, but have been dormant for some time. Tired of my posts there being "decorated" by the hosting provider without approval and inspired by [Fabien Sanglard](https://fabiensanglard.net/bloated/index.html), I'm rebooting here.
-Posts prior to this one are copied from Blogger or Medium. Forgive me for all their historical naiveté. Posts after this are new here, and I'm sure will look equally silly in ten years.
+Posts prior to this one are copied from Blogger or Medium. Forgive me for all their historical naiveté. Posts after this are new here, and I'm sure will look equally silly in ten years. The historical posts have been hand-translated to markdown and likely contain translation errors.
diff --git a/markdown/build-html.sh b/markdown/build-html.sh
index 6720197..b2d9628 100755
--- a/markdown/build-html.sh
+++ b/markdown/build-html.sh
@@ -4,6 +4,9 @@ BASEDIR=$(dirname $0)
for FILE in $BASEDIR/*.md; do
BASENAME=$(basename $FILE)
+ if [[ $BASENAME == 'template.md' ]]; then
+ continue
+ fi
OUTNAME=${BASENAME%.md}.html
echo "$BASENAME -> $OUTNAME"
TEMP=$(tempfile --dir=$BASEDIR --mode=0644 --suffix=.tmp)
diff --git a/markdown/index.md b/markdown/index.md
new file mode 100644
index 0000000..0691bb0
--- /dev/null
+++ b/markdown/index.md
@@ -0,0 +1,12 @@
+
+
+
+
+1. 2019-Apr-14: [Reboot](2019-04-14-reboot.html)
+1. 2016-May-17: [WiFi bridging redux](2016-05-17-wifi-bridging-redux.html)
+1. 2016-Apr-02: [apt caching for debootstrap](2016-04-02-apt-caching-for-debootstrap.html)
+1. 2016-Mar-27: [EC CA redux: now with more Nitrokey](2016-03-27-ec-ca-redux-now-with-more-nitrokey.html)
+1. 2016-Mar-26: [Nitrokey HSM EC setup](2016-03-26-nitrokey-hsm-ec-setup.html)
+1. 2016-Mar-21: [Elliptic Curve Certificate Authority](2016-03-21-elliptic-curve-certificate-authority.html)
+
+
diff --git a/template.html b/markdown/template.md
similarity index 97%
rename from template.html
rename to markdown/template.md
index eac693d..3b89d49 100644
--- a/template.html
+++ b/markdown/template.md
@@ -3,6 +3,6 @@
-
+X