Commit | Line | Data |
---|---|---|
5fb66a7a MW |
1 | ### -*-sh-*- |
2 | ### | |
3 | ### Key type for OpenSSL | |
4 | ### | |
5 | ### (c) 2015 Mark Wooding | |
6 | ### | |
7 | ||
8 | ###----- Licensing notice --------------------------------------------------- | |
9 | ### | |
10 | ### This file is part of the distorted.org.uk key management suite. | |
11 | ### | |
12 | ### distorted-keys is free software; you can redistribute it and/or modify | |
13 | ### it under the terms of the GNU General Public License as published by | |
14 | ### the Free Software Foundation; either version 2 of the License, or | |
15 | ### (at your option) any later version. | |
16 | ### | |
17 | ### distorted-keys is distributed in the hope that it will be useful, | |
18 | ### but WITHOUT ANY WARRANTY; without even the implied warranty of | |
19 | ### MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
20 | ### GNU General Public License for more details. | |
21 | ### | |
22 | ### You should have received a copy of the GNU General Public License | |
23 | ### along with distorted-keys; if not, write to the Free Software Foundation, | |
24 | ### Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. | |
25 | ||
26 | R_OPT="$R_IDENT:$R_IDENT" | |
27 | R_OPTSEQ="$R_OPT\([[:space:]][[:space:]]*$R_OPT\)*" | |
28 | ||
29 | R_TYPE="[$R_IDENTCHARS[:space:]][$R_IDENTCHARS[:space:]]*" | |
30 | R_BASE64="[a-zA-Z0-9+/]*=*" | |
31 | R_PARAMS="$R_TYPE:$R_BASE64" | |
32 | ||
33 | defprops k_props <<EOF | |
34 | algorithm t $R_WORD | |
35 | opts t $R_OPTSEQ | |
36 | params t $R_PARAMS | |
37 | fresh_params_p t $R_IDENT | |
38 | cipher t $R_WORD | |
39 | sig_opts t $R_OPTSEQ | |
40 | enc_opts t $R_OPTSEQ | |
41 | EOF | |
42 | ||
43 | : ${kprop_cipher=aes-256-cbc} | |
44 | : ${kprop_fresh_params_p=nil}; boolify kprop_fresh_params_p | |
45 | have_opts_p=${kprop_opts+t}${kprop_opts-nil} | |
46 | have_params_p=${kprop_params+t}${kprop_params-nil} | |
47 | have_alg_p=${kprop_algorithm+t}${kprop_algorithm-nil} | |
48 | ||
49 | pem_to_line () { | |
50 | ## Read an OpenSSL PEM file from stdin and write a condensed one-line | |
51 | ## version to stdout. | |
52 | sed '/^-----BEGIN \(.*\)-----$/s//\1:/; /^-----END .*-----$/d' | | |
53 | tr -d '\n' | |
54 | } | |
55 | ||
56 | line_to_pem () { | |
57 | line=$1 | |
58 | ## Write to stdout an OpenSSL PEM file corresponding to LINE. | |
59 | ||
60 | ty=${line%%:*} | |
61 | echo "-----BEGIN $ty-----" | |
62 | echo "${line#*:}" | fold -w64 | |
63 | echo "-----END $ty-----"; | |
64 | } | |
65 | ||
66 | intersperse_opts () { | |
67 | flag=$1 opts=$2 | |
68 | ||
69 | args= sep= | |
70 | for i in $opts; do args="$args$sep$flag $i" sep=" "; done | |
71 | echo "$args" | |
72 | } | |
73 | ||
74 | k_generate() { | |
75 | base=$1 nub=$2 | |
76 | ||
77 | ## Convert the options into OpenSSL command-line options. | |
78 | opts=$(intersperse_opts -pkeyopt "$kprop_opts") | |
79 | ||
80 | ## Prepare our ducks, ensuring that they're collinear. | |
81 | case $have_params_p,$have_alg_p,$kprop_fresh_params_p,$have_opts_p in | |
82 | t,nil,nil,nil) | |
83 | line_to_pem "$kprop_params" >$TMP/param | |
84 | args="-paramfile $TMP/param" | |
85 | ;; | |
86 | nil,t,t,*) | |
87 | openssl genpkey -genparam -algorithm $kprop_algorithm $opts >$TMP/param | |
88 | args="-paramfile $TMP/param" | |
89 | ;; | |
90 | nil,t,nil,*) | |
91 | args="-algorithm $kprop_algorithm $opts" | |
92 | ;; | |
93 | *) | |
94 | echo >&2 "$quis: invalid combination of properties" | |
95 | exit 1 | |
96 | ;; | |
97 | esac | |
98 | ||
99 | ## Generate the private key. | |
100 | openssl -cipher $kprop_cipher -pass file:"$nub" -out "$base/priv" | |
101 | ||
102 | ## Extract the public key. | |
103 | openssl -passin file:"$nub" -in "$base/priv" -pubout "$base/pub" | |
104 | } | |
105 | ||
106 | k_encrypt () { | |
107 | base=$1 | |
108 | ||
109 | openssl pkeyutl -encrypt -pubin -inkey "$base/pub" \ | |
110 | $(intersperse_opts -pkeyopt "$kprop_enc_opts") | |
111 | } | |
112 | ||
113 | k_decrypt () { | |
114 | base=$1 nub=$2 | |
115 | ||
116 | openssl pkeyutl -decrypt -passin file:"$nub" -inkey "$base/priv" | |
117 | } | |
118 | ||
119 | k_sign () { | |
120 | base=$1 nub=$2 | |
121 | ||
122 | openssl pkeyutl -sign -passin file:"$nub" -inkey "$base/priv" \ | |
123 | $(intersperse_opts -pkeyopt "$kprop_sig_opts") >$TMP/sig | |
124 | pem_to_line <$TMP/sig | |
125 | } | |
126 | ||
127 | k_verify () { | |
128 | base=$1 sig=$3 | |
129 | ||
130 | line_to_pem "$3" >$TMP/sig | |
131 | openssl pkeyutl -verify -pubin -inkey "$base/pub" -sigfile $TMP/sig | |
132 | } | |
133 | ||
134 | ###----- That's all, folks -------------------------------------------------- |