aboutsummaryrefslogtreecommitdiff
path: root/share/keyringer/genpair
blob: cffed9402f9575e0b334e98e842b8a0d2c6978b9 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
#!/bin/bash
#
# Generate keypairs.
#
# This script is just a wrapper to easily generate keys for
# automated systems.
# 

# Generate a keypair, ssh version
function genpair_ssh {
  echo "Make sure that $KEYDIR is atop of an encrypted volume."
  read -p "Hit ENTER to continue." prompt

  # TODO: programatically enter blank passphrase twice
  ssh-keygen -t rsa -f "$TMPWORK/id_rsa" -C "root@$NODE"

  # Encrypt the result
  echo "Encrypting secret key into keyringer..."
  cat "$TMPWORK/id_rsa"     | keyringer_exec encrypt "$BASEDIR" "$FILE"
  echo "Encrypting public key into keyringer..."
  cat "$TMPWORK/id_rsa.pub" | keyringer_exec encrypt "$BASEDIR" "$FILE.pub"

  # TODO: add outfiles into version control
  if [ ! -z "$OUTFILE" ]; then
    mkdir -p `dirname $OUTFILE`
    printf "Saving copies at %s and %s.pub\n" "$OUTFILE" "$OUTFILE"
    cat "$TMPWORK/id_rsa"     > "$OUTFILE"
    cat "$TMPWORK/id_rsa.pub" > "$OUTFILE.pub"
  fi

  echo "Done"  
}

# Generate a keypair, gpg version
function genpair_gpg {
  echo "Make sure that $KEYDIR is atop of an encrypted volume."

  passphrase="no"
  passphrase_confirm="confirm"

  while [ "$passphrase" != "$passphrase_confirm" ]; do
    read -s -p "Enter password for the private key: " passphrase
    printf "\n"
    read -s -p "Enter password again: " passphrase_confirm
    printf "\n"

    if [ "$passphrase" != "$passphrase_confirm" ]; then
      echo "Password don't match."
    fi
  done
  
  # TODO: insert random bytes
  # TODO: custom Name-Comment and Name-Email
  # TODO: allow for empty passphrases
  gpg --homedir "$TMPWORK" --gen-key --batch <<EOF
    Key-Type: RSA
    Key-Length: 4096
    Subkey-Type: ELG-E
    Subkey-Length: 4096
    Name-Real: $NODE
    Name-Email: root@$NODE
    Expire-Date: 0
    Passphrase: $passphrase
    %commit
EOF

  # Encrypt the result
  echo "Encrypting secret key into keyringer..."
  gpg --armor --homedir "$TMPWORK" --export-secret-keys | keyringer_exec encrypt "$BASEDIR" "$FILE"
  echo "Encrypting public key into keyringer..."
  gpg --armor --homedir "$TMPWORK" --export             | keyringer_exec encrypt "$BASEDIR" "$FILE.pub"
  echo "Encrypting passphrase into keyringer..."
  echo "Passphrase for $FILE: $passphrase"              | keyringer_exec encrypt "$BASEDIR" "$FILE.passwd"

  # TODO: add outfiles into version control
  if [ ! -z "$OUTFILE" ]; then
    mkdir -p `dirname $OUTFILE`
    printf "Saving copies at %s and %s.pub\n" "$OUTFILE" "$OUTFILE"
    gpg --armor --homedir "$TMPWORK" --export-secret-keys > "$OUTFILE"
    gpg --armor --homedir "$TMPWORK" --export             > "$OUTFILE.pub"
  fi

  echo "Done"  
}

# Generate a keypair, ssl version
# TODO: add the possibility of SubjectAltNames also for ssl-self and ssl modes
#       so wildcard certs can work correctly.
function genpair_ssl {
  echo "Make sure that $KEYDIR is atop of an encrypted volume."
  read -p "Hit ENTER to continue." prompt

  # Setup
  cd "$TMPWORK"

  # Generate certificate
  if [ "$KEYTYPE" == "ssl-cacert" ]; then
    "$LIB/csr.sh" "$NODE"
  else
    openssl req -nodes -newkey rsa:2048 -keyout ${NODE}_privatekey.pem -out ${NODE}_csr.pem
  fi

  # Self-sign
  if [ "$KEYTYPE" == "ssl-self" ]; then
    openssl x509 -in "${NODE}_csr.pem" -out "$NODE.crt" -req -signkey "${NODE}_privatekey.pem" -days 365
    chmod 600 "${NODE}_privatekey.pem"
  fi

  # Encrypt the result
  echo "Encrypting private key into keyringer..."
  cat "${NODE}_privatekey.pem" | keyringer_exec encrypt "$BASEDIR" "$FILE.pem"
  echo "Encrypting certificate request into keyringer..."
  cat "${NODE}_csr.pem"        | keyringer_exec encrypt "$BASEDIR" "$FILE.csr"
  
  if [ "$KEYTYPE" == "ssl-self" ]; then
    echo "Encrypting certificate into keyringer..."
    cat "$NODE.crt"              | keyringer_exec encrypt "$BASEDIR" "$FILE.crt"
  elif [ -f "$BASEDIR/keys/$FILE.crt.asc" ]; then
    # Remove any existing crt
    keyringer_exec del "$BASEDIR" "$FILE.crt"
  fi

  cd "$CWD"

  if [ ! -z "$OUTFILE" ]; then
    mkdir -p `dirname $OUTFILE`
    printf "Saving copies at %s.pem, %s.csr and %s.crt\n" "$OUTFILE" "$OUTFILE" "$OUTFILE"
    cat "$TMPWORK/${NODE}_privatekey.pem" > "$OUTFILE.pem"
    cat "$TMPWORK/${NODE}_csr.pem"        > "$OUTFILE.csr"

    if [ -f "$TMPWORK/$NODE.crt" ]; then
      cat "$TMPWORK/$NODE.crt"              > "$OUTFILE.crt"
    fi
  fi

  # Show cert fingerprint
  if [ "$KEYTYPE" == "ssl-self" ]; then
    openssl x509 -noout -in "$TMPWORK/$NODE.crt" -fingerprint
  fi

  echo "Done"
}

# Load functions
LIB="`dirname $0`/../../lib/keyringer"
source "$LIB/functions" || exit 1

# Aditional parameters
KEYTYPE="$2"
FILE="$3"
NODE="$4"
OUTFILE="$5"
CWD="`pwd`"

# Verify
if [ -z "$NODE" ]; then
  echo -e "Usage: keyringer <keyring> $BASENAME <gpg|ssh|ssl|ssl-cacert|ssl-self> <file> <hostname> [outfile]"
  echo -e "Options:"
  echo -e "\t gpg|ssh|ssl: key type."
  echo -e "\t file       : base file name for encrypted output (relative to keys folder)"
  echo -e "\t hostname   : host for the key pair"
  echo -e "\t outfile    : optional unencrypted output file, useful for deployment"
  exit 1
elif [ ! -e "$KEYDIR" ]; then
  echo "Folder not found: $KEYDIR, leaving"
  exit 1
fi

# Set a tmp file
keyringer_set_tmpfile genpair -d

# Dispatch
echo "Generating $KEYTYPE key for $NODE..."
if [ "$KEYTYPE" == "ssl-self" ] || [ "$KEYTYPE" == "ssl-cacert" ]; then
  genpair_ssl
else
  genpair_"$KEYTYPE"
fi

# Cleanup
cd "$CWD"
rm -rf "$TMPWORK"
trap - EXIT