~dricottone/my-utils

my-utils/crypto/keytype -rwxr-xr-x 3.4 KiB
ef6d4cd1Dominic Ricottone Incomplete work on hardware/media utils 4 days ago
                                                                                
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
#!/bin/bash

name="keytype"
version="1.0"
read -r -d '' help_message <<-EOF
	Inspect a cryptographic key for type and length
	Usage: keytype [OPTIONS] KEYFILE
	Options:
	 -h, --help     print this message and exit
	 -q, --quiet    suppress error messages and prompts
	 -v, --verbose  show additional messages
	 -V, --version  print version number and exit
EOF

source /usr/local/lib/mylib.bash

quiet=0
verbose=0
while [[ $# -gt 0 ]]; do
  case "$1" in

  -h|--help)
    help_msg
    shift
    ;;

  -q|--quiet)
    debug_msg "Setting quiet option to 1 (was ${quiet})"
    quiet=1
    shift
    ;;

  -v|--verbose)
    debug_msg "Setting verbose option to 1 (was ${verbose})"
    verbose=1
    shift
    ;;

  -V|--version)
    version_msg
    ;;

  *)
    debug_msg "Argument '${1}' added to positional array"
    positional+=("$1")
    shift
    ;;
  esac
done

try_openssh() {
  keylength=
  keyfingerprint=
  keytype=
  keycomment=

  keyinfo="$(/usr/bin/ssh-keygen -l -f "$keyfile" 2>/dev/null)"

  if [ $? -ne 0 ]; then
    debug_msg "file '${keyfile}' is not an OpenSSH key"
    return 1
  else
    keylength="$(/usr/bin/cut --delimiter=' ' --field=1 <<<"$keyinfo")"
    keyfingerprint="$(/usr/bin/cut --delimiter=' ' --field=2 <<<"$keyinfo")"
    keycomment="$(/usr/bin/awk '{$1=$2=$NF="";print substr($0,3,length($0)-3)}' <<<"$keyinfo")"
    keytype="$(/usr/bin/awk '{print substr($NF,2,length($NF)-2)}' <<<"$keyinfo")"

    /usr/bin/printf "%s: %s-bit %s OpenSSH key\n" "${keyfile}" "${keylength}" "${keytype}"
    return 0
  fi
}

try_openpgp() {
  keyinfo=
  keyprivacy=
  keylength=
  keytypenum=
  keytype=
  keyfingerprint=

  keyinfodump="$(/usr/bin/gpg2 --show-keys --with-colons "$keyfile" 2>/dev/null)"

  if [ $? -ne 0 ]; then
    debug_msg "file '${keyfile}' is not an OpenPGP key"
    return 1
  else
    if /usr/bin/grep -e "^pub:" <<<"$keyinfodump" >/dev/null 2>&1; then
      keyprivacy="public"
      keyinfo="$(/usr/bin/grep -e "^pub:" <<<"$keyinfodump")"
    elif /usr/bin/grep -e "^sec:" <<<"$keyinfodump" >/dev/null 2>&1; then
      keyprivacy="private"
      keyinfo="$(/usr/bin/grep -e "^sec:" <<<"$keyinfodump")"
    else
      debug_msg "file '${keyfile}' is an OpenPGP key, but it cannot be interpretted"
    fi

    keylength="$(/usr/bin/cut --delimiter=':' --field=3 <<<"$keyinfo")"
    keytypenum="$(/usr/bin/cut --delimiter=':' --field=4 <<<"$keyinfo")"

    case "$keytypenum" in
    1)
      keytype="RSA"
      ;;

    16)
      keytype="Elgamel"
      ;;

    17)
      keytype="DSA"
      ;;

    *)
      error_msg "Unknown algorythm on OpenPGP key"
      ;;

    #2 is deprecated as RSA Encrypt Only
    #3 is deprecated as RSA Sign Only
    #18 is reserved for Elliptic Curve but not part of the OpenPGP spec yet
    #19 is reserved for ECDSA but not part of the OpenPGP spec yet
    #20 is reserved; deprecated as Elgamel Encrypt or Sign
    #21 is reserved for Diffie-Hellman but not part of the OpenPGP spec yet
    #100-110 are reserved for experimental use
    #256+ are reserved for Libgcrypt to allocate
    esac

    keyfingerprint="$(/usr/bin/cut --delimiter=':' --field=5 <<<"$keyinfo")"

    /usr/bin/printf "%s: %s-bit %s %s OpenPGP key\n" "${keyfile}" "${keylength}" "${keyprivacy}" "${keytype}"
    return 0
  fi
}

try_openssl() {
  #TODO: implement OpenSSL checks
  :
}

code=0
for keyfile in "${positional[@]}"; do
  if ! try_openssh; then
    if ! try_openpgp; then
      if ! try_openssl; then
        code=1
      fi
    fi
  fi
done

exit "$code"