]> git.ipfire.org Git - thirdparty/strongswan.git/blame - src/pki/commands/keyid.c
Update copyright headers after acquisition by secunet
[thirdparty/strongswan.git] / src / pki / commands / keyid.c
CommitLineData
6be68cc1
MW
1/*
2 * Copyright (C) 2009 Martin Willi
ab94f76d 3 * Copyright (C) 2017 Andreas Steffen
19ef2aec
TB
4 *
5 * Copyright (C) secunet Security Networks AG
6be68cc1
MW
6 *
7 * This program is free software; you can redistribute it and/or modify it
8 * under the terms of the GNU General Public License as published by the
9 * Free Software Foundation; either version 2 of the License, or (at your
10 * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
11 *
12 * This program is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
14 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
15 * for more details.
16 */
17
1c4a3459
MW
18#include <errno.h>
19
6be68cc1
MW
20#include "pki.h"
21
22#include <credentials/certificates/certificate.h>
23#include <credentials/certificates/x509.h>
24
0c924641
TB
25typedef enum {
26 FORMAT_PRETTY,
27 FORMAT_HEX,
28 FORMAT_BASE64,
29 FORMAT_BINARY,
30} format_t;
31
32/**
33 * Print a single keyid in the requested format
34 */
35static bool print_id(chunk_t id, format_t format, char *desc)
36{
37 chunk_t chunk;
38
39 switch (format)
40 {
41 case FORMAT_PRETTY:
42 printf("%s:\n %#B\n", desc, &id);
43 break;
44 case FORMAT_HEX:
45 chunk = chunk_to_hex(id, NULL, FALSE);
46 printf("%.*s\n", (int)chunk.len, chunk.ptr);
47 chunk_free(&chunk);
48 break;
49 case FORMAT_BASE64:
50 chunk = chunk_to_base64(id, NULL);
51 printf("%.*s\n", (int)chunk.len, chunk.ptr);
52 chunk_free(&chunk);
53 break;
54 case FORMAT_BINARY:
55 if (fwrite(id.ptr, id.len, 1, stdout) != 1)
56 {
57 fprintf(stderr, "writing %s failed\n", desc);
58 return FALSE;
59 }
60 break;
61 }
62 return TRUE;
63}
64
6be68cc1
MW
65/**
66 * Calculate the keyid of a key/certificate
67 */
ae7452e8 68static int keyid()
6be68cc1
MW
69{
70 credential_type_t type = CRED_PRIVATE_KEY;
05ccde0a 71 int subtype = KEY_ANY;
6be68cc1
MW
72 certificate_t *cert;
73 private_key_t *private;
74 public_key_t *public;
0c924641
TB
75 format_t format = FORMAT_PRETTY;
76 enum {
77 ID_TYPE_ALL,
78 ID_TYPE_SPK,
79 ID_TYPE_SPKI,
2403154f 80 } id_type = ID_TYPE_ALL;
ab94f76d 81 char *file = NULL, *keyid = NULL;
6be68cc1 82 void *cred;
0c924641 83 chunk_t id, spk = chunk_empty, spki = chunk_empty;
ae7452e8 84 char *arg;
6be68cc1
MW
85
86 while (TRUE)
87 {
ae7452e8 88 switch (command_getopt(&arg))
6be68cc1
MW
89 {
90 case 'h':
3ce9438b 91 return command_usage(NULL);
6be68cc1 92 case 't':
1798e490
TB
93 if (streq(arg, "rsa") ||
94 streq(arg, "rsa-priv"))
6be68cc1
MW
95 {
96 type = CRED_PRIVATE_KEY;
97 subtype = KEY_RSA;
98 }
1798e490
TB
99 else if (streq(arg, "ecdsa") ||
100 streq(arg, "ecdsa-priv"))
6be68cc1
MW
101 {
102 type = CRED_PRIVATE_KEY;
103 subtype = KEY_ECDSA;
104 }
1798e490
TB
105 else if (streq(arg, "bliss") ||
106 streq(arg, "bliss-priv"))
b6bb32e6
AS
107 {
108 type = CRED_PRIVATE_KEY;
109 subtype = KEY_BLISS;
110 }
05ccde0a
TB
111 else if (streq(arg, "priv"))
112 {
113 type = CRED_PRIVATE_KEY;
114 subtype = KEY_ANY;
115 }
ae7452e8 116 else if (streq(arg, "pub"))
6be68cc1
MW
117 {
118 type = CRED_PUBLIC_KEY;
119 subtype = KEY_ANY;
120 }
ae7452e8 121 else if (streq(arg, "pkcs10"))
622e558c
AS
122 {
123 type = CRED_CERTIFICATE;
124 subtype = CERT_PKCS10_REQUEST;
125 }
ae7452e8 126 else if (streq(arg, "x509"))
6be68cc1
MW
127 {
128 type = CRED_CERTIFICATE;
129 subtype = CERT_X509;
130 }
131 else
132 {
3ce9438b 133 return command_usage( "invalid input type");
6be68cc1
MW
134 }
135 continue;
0c924641
TB
136 case 'I':
137 if (streq(arg, "spk"))
138 {
139 id_type = ID_TYPE_SPK;
140 }
141 else if (streq(arg, "spki"))
142 {
143 id_type = ID_TYPE_SPKI;
144 }
145 else if (!streq(arg, "all"))
146 {
147 return command_usage( "invalid id type");
148 }
149 continue;
150 case 'f':
151 if (streq(arg, "hex"))
152 {
153 format = FORMAT_HEX;
154 }
155 else if (streq(arg, "base64"))
156 {
157 format = FORMAT_BASE64;
158 }
159 else if (streq(arg, "bin"))
160 {
161 format = FORMAT_BINARY;
162 }
163 else if (!streq(arg, "pretty"))
164 {
165 return command_usage( "invalid output format");
166 }
167 continue;
6be68cc1 168 case 'i':
ae7452e8 169 file = arg;
6be68cc1 170 continue;
ab94f76d
AS
171 case 'x':
172 keyid = arg;
173 continue;
6be68cc1
MW
174 case EOF:
175 break;
176 default:
3ce9438b 177 return command_usage("invalid --keyid option");
6be68cc1
MW
178 }
179 break;
180 }
181 if (file)
182 {
183 cred = lib->creds->create(lib->creds, type, subtype,
184 BUILD_FROM_FILE, file, BUILD_END);
185 }
ab94f76d
AS
186 else if (keyid)
187 {
188 chunk_t chunk;
189
190 chunk = chunk_from_hex(chunk_create(keyid, strlen(keyid)), NULL);
191 cred = lib->creds->create(lib->creds, CRED_PRIVATE_KEY, KEY_ANY,
192 BUILD_PKCS11_KEYID, chunk, BUILD_END);
193 free(chunk.ptr);
194 }
6be68cc1
MW
195 else
196 {
71c9565a
TB
197 chunk_t chunk;
198
13298719 199 set_file_mode(stdin, CERT_ASN1_DER);
1c4a3459
MW
200 if (!chunk_from_fd(0, &chunk))
201 {
202 fprintf(stderr, "reading input failed: %s\n", strerror(errno));
203 return 1;
204 }
6be68cc1 205 cred = lib->creds->create(lib->creds, type, subtype,
71c9565a
TB
206 BUILD_BLOB, chunk, BUILD_END);
207 free(chunk.ptr);
6be68cc1
MW
208 }
209 if (!cred)
210 {
211 fprintf(stderr, "parsing input failed\n");
212 return 1;
213 }
214
215 if (type == CRED_PRIVATE_KEY)
216 {
217 private = cred;
da9724e6 218 if (private->get_fingerprint(private, KEYID_PUBKEY_SHA1, &id))
6be68cc1 219 {
0c924641 220 spk = chunk_clone(id);
6be68cc1 221 }
da9724e6 222 if (private->get_fingerprint(private, KEYID_PUBKEY_INFO_SHA1, &id))
6be68cc1 223 {
0c924641 224 spki = chunk_clone(id);
6be68cc1
MW
225 }
226 private->destroy(private);
227 }
228 else if (type == CRED_PUBLIC_KEY)
229 {
230 public = cred;
da9724e6 231 if (public->get_fingerprint(public, KEYID_PUBKEY_SHA1, &id))
6be68cc1 232 {
0c924641 233 spk = chunk_clone(id);
6be68cc1 234 }
da9724e6 235 if (public->get_fingerprint(public, KEYID_PUBKEY_INFO_SHA1, &id))
6be68cc1 236 {
0c924641 237 spki = chunk_clone(id);
6be68cc1
MW
238 }
239 public->destroy(public);
240 }
241 else
242 {
243 cert = cred;
244 public = cert->get_public_key(cert);
245 if (!public)
246 {
247 fprintf(stderr, "extracting public key from certificate failed");
248 return 1;
249 }
da9724e6 250 if (public->get_fingerprint(public, KEYID_PUBKEY_SHA1, &id))
6be68cc1 251 {
0c924641 252 spk = chunk_clone(id);
6be68cc1 253 }
da9724e6 254 if (public->get_fingerprint(public, KEYID_PUBKEY_INFO_SHA1, &id))
6be68cc1 255 {
0c924641 256 spki = chunk_clone(id);
6be68cc1
MW
257 }
258 public->destroy(public);
259 cert->destroy(cert);
260 }
0c924641
TB
261
262 if (id_type == ID_TYPE_ALL || id_type == ID_TYPE_SPK)
263 {
264 if (!spk.len ||
265 !print_id(spk, format, "subjkey (SHA-1 of subjectPublicKey)"))
266 {
267 return 1;
268 }
269 }
270 if (id_type == ID_TYPE_ALL || id_type == ID_TYPE_SPKI)
271 {
272 if (!spki.len ||
273 !print_id(spki, format, "keyid (SHA-1 of subjectPublicKeyInfo)"))
274 {
275 return 1;
276 }
277 }
278 chunk_free(&spk);
279 chunk_free(&spki);
6be68cc1
MW
280 return 0;
281}
282
283/**
284 * Register the command.
285 */
286static void __attribute__ ((constructor))reg()
287{
3ce9438b 288 command_register((command_t)
6be68cc1
MW
289 { keyid, 'k', "keyid",
290 "calculate key identifiers of a key/certificate",
0c924641
TB
291 {"[--in file|--keyid hex] [--type priv|rsa|ecdsa|bliss|pub|pkcs10|x509]",
292 "[--id all|spk|spki] [--format pretty|hex|base64|bin]"},
6be68cc1
MW
293 {
294 {"help", 'h', 0, "show usage information"},
295 {"in", 'i', 1, "input file, default: stdin"},
ab94f76d 296 {"keyid", 'x', 1, "smartcard or TPM private key object handle"},
05ccde0a 297 {"type", 't', 1, "type of key, default: priv"},
0c924641
TB
298 {"id", 'I', 1, "type of identifier, default: all"},
299 {"format", 'f', 1, "output format, default: pretty"},
6be68cc1
MW
300 }
301 });
302}