summaryrefslogtreecommitdiff
path: root/examples/make-x509-certreqs
blob: 6ff82a03990e0854db52188103a04134b35cfc94 (plain)
  1. #!/bin/bash
  2. # Author: Daniel Kahn Gillmor <dkg@fifthhorseman.net>
  3. # Date: 2010-12-20 20:54:55-0500
  4. # On a system with keys for https (or some other X.509-using protocol)
  5. # already imported into monkeysphere-host, this script generates X.509
  6. # certificate requests for each key, with appropriate subjectAltNames
  7. # and the PGPExtension embedded.
  8. # The generated requests get dumped to stdout. redirect to a file or
  9. # copy/paste if you want to save them/send them someplace.
  10. # This script uses bashisms
  11. # It currently needs OpenSSL binaries to work properly
  12. # It assumes that the monkeysphere-host keyring is in
  13. # /var/lib/monkeysphere/host (which it is on debian)
  14. # This should probably eventually be incorporated into
  15. # monkeysphere-host directly.
  16. get_openssl_config() {
  17. # first param is seconds since the epoch:
  18. X509_PGP_EXTENSION="$(TZ=UTC date -d "@$1" '+%Y%m%d%H%M%SZ')"
  19. # next parameter is SAN names, separated by newlines:
  20. SUBJECTALTNAME=$(printf "%s" "$2" | sed 's/^/DNS:/' | tr '\n' ',' | \
  21. sed -e 's/,*$//' -e 's/^,*//')
  22. printf "sAN: %s\n" "$SUBJECTALTNAME" >&2
  23. cat <<EOF
  24. default_md = sha256
  25. oid_section = new_oids
  26. [ new_oids ]
  27. PGPExtension = 1.3.6.1.4.1.3401.8.1.1
  28. [ req ]
  29. distinguished_name = req_distinguished_name
  30. req_extensions = v3_req # The extensions to add to a certificate request
  31. [ req_distinguished_name ]
  32. commonName = Common Name (e.g. www.example.org)
  33. commonName_max = 64
  34. [ v3_req ]
  35. # Extensions to add to a certificate request
  36. basicConstraints = CA:FALSE
  37. keyUsage = nonRepudiation, digitalSignature, keyEncipherment
  38. extendedKeyUsage = serverAuth
  39. subjectAltName = $SUBJECTALTNAME
  40. PGPExtension = ASN1:SEQUENCE:pgp_sect
  41. [ pgp_sect ]
  42. # see http://www.alvestrand.no/objectid/submissions/1.3.6.1.4.1.3401.8.1.1.html
  43. # this is equivalent to:
  44. # Version ::= INTEGER { v1(0) }
  45. version = INTEGER:0
  46. # this is the OpenPGP creation timestamp
  47. keyCreation = GENERALIZEDTIME:$X509_PGP_EXTENSION
  48. EOF
  49. }
  50. gencertreq() {
  51. keyid="$1"
  52. timestamp=$(gpg --fixed-list-mode --with-colons --list-keys "0x$keyid!" | grep ^pub: | cut -f6 -d:)
  53. san=''
  54. primary=''
  55. # find all the $proto-using User IDs:
  56. uids=$(gpg --fixed-list-mode --with-colons --list-keys "0x$keyid!" | \
  57. grep '^uid:' | cut -f10 -d: | \
  58. grep '^'"${proto}"'\\x3a//' | \
  59. sed -r -e 's!^'"${proto}"'\\x3a//!!' -e 's!:[0-9]+$!!')
  60. primary=$(printf "%s" "$uids" | head -n1)
  61. printf "Certificate Request for TLS WWW server %s\n[OpenPGP key %s]\n" "$primary" "$keyid"
  62. openssl req -text -new \
  63. -config <(get_openssl_config "$timestamp" "$uids") \
  64. -key <(gpg --export-secret-key "$keyid" | openpgp2ssh "$keyid") \
  65. -subj "/CN=${primary}/"
  66. }
  67. export GNUPGHOME=/var/lib/monkeysphere/host
  68. # default to looking for https keys.
  69. proto="${1:-https}"
  70. for fpr in $(gpg --fixed-list-mode --with-colons --fingerprint --list-secret-keys "${proto}://" | grep '^fpr:' | cut -f10 -d:); do
  71. gencertreq "$fpr"
  72. done