pki: Add support for Ed448 keys/certificates
[strongswan.git] / src / pki / commands / print.c
1 /*
2 * Copyright (C) 2010 Martin Willi
3 * Copyright (C) 2010 revosec AG
4 *
5 * Copyright (C) 2015-2016 Andreas Steffen
6 * HSR Hochschule fuer Technik Rapperswil
7 *
8 * This program is free software; you can redistribute it and/or modify it
9 * under the terms of the GNU General Public License as published by the
10 * Free Software Foundation; either version 2 of the License, or (at your
11 * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
12 *
13 * This program is distributed in the hope that it will be useful, but
14 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
15 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
16 * for more details.
17 */
18
19 #include "pki.h"
20
21 #include <credentials/certificates/certificate.h>
22 #include <credentials/certificates/certificate_printer.h>
23
24 #include <errno.h>
25
26 /**
27 * Print private key information
28 */
29 static void print_key(private_key_t *key)
30 {
31 public_key_t *public;
32 chunk_t chunk;
33
34 public = key->get_public_key(key);
35 if (public)
36 {
37 printf(" privkey: %N %d bits\n", key_type_names,
38 public->get_type(public), public->get_keysize(public));
39 if (public->get_fingerprint(public, KEYID_PUBKEY_INFO_SHA1, &chunk))
40 {
41 printf(" keyid: %#B\n", &chunk);
42 }
43 if (public->get_fingerprint(public, KEYID_PUBKEY_SHA1, &chunk))
44 {
45 printf(" subjkey: %#B\n", &chunk);
46 }
47 public->destroy(public);
48 }
49 else
50 {
51 printf("extracting public from private key failed\n");
52 }
53 }
54
55 /**
56 * Print a credential in a human readable form
57 */
58 static int print()
59 {
60 credential_type_t type = CRED_CERTIFICATE;
61 int subtype = CERT_X509;
62 void *cred;
63 char *arg, *file = NULL, *keyid = NULL;
64 chunk_t chunk;
65
66 while (TRUE)
67 {
68 switch (command_getopt(&arg))
69 {
70 case 'h':
71 return command_usage(NULL);
72 case 't':
73 if (streq(arg, "x509"))
74 {
75 type = CRED_CERTIFICATE;
76 subtype = CERT_X509;
77 }
78 else if (streq(arg, "crl"))
79 {
80 type = CRED_CERTIFICATE;
81 subtype = CERT_X509_CRL;
82 }
83 else if (streq(arg, "ac"))
84 {
85 type = CRED_CERTIFICATE;
86 subtype = CERT_X509_AC;
87 }
88 else if (streq(arg, "pub"))
89 {
90 type = CRED_CERTIFICATE;
91 subtype = CERT_TRUSTED_PUBKEY;
92 }
93 else if (streq(arg, "priv"))
94 {
95 type = CRED_PRIVATE_KEY;
96 subtype = KEY_ANY;
97 }
98 else if (streq(arg, "rsa") ||
99 streq(arg, "rsa-priv"))
100 {
101 type = CRED_PRIVATE_KEY;
102 subtype = KEY_RSA;
103 }
104 else if (streq(arg, "ecdsa") ||
105 streq(arg, "ecdsa-priv"))
106 {
107 type = CRED_PRIVATE_KEY;
108 subtype = KEY_ECDSA;
109 }
110 else if (streq(arg, "ed25519") ||
111 streq(arg, "ed25519-priv"))
112 {
113 type = CRED_PRIVATE_KEY;
114 subtype = KEY_ED25519;
115 }
116 else if (streq(arg, "ed448") ||
117 streq(arg, "ed448-priv"))
118 {
119 type = CRED_PRIVATE_KEY;
120 subtype = KEY_ED448;
121 }
122 else if (streq(arg, "bliss") ||
123 streq(arg, "bliss-priv"))
124 {
125 type = CRED_PRIVATE_KEY;
126 subtype = KEY_BLISS;
127 }
128 else
129 {
130 return command_usage( "invalid input type");
131 }
132 continue;
133 case 'i':
134 file = arg;
135 continue;
136 case 'x':
137 keyid = arg;
138 continue;
139 case EOF:
140 break;
141 default:
142 return command_usage("invalid --print option");
143 }
144 break;
145 }
146 if (keyid)
147 {
148 chunk = chunk_from_hex(chunk_create(keyid, strlen(keyid)), NULL);
149 cred = lib->creds->create(lib->creds, type, subtype,
150 BUILD_PKCS11_KEYID, chunk, BUILD_END);
151 free(chunk.ptr);
152 }
153 else if (file)
154 {
155 cred = lib->creds->create(lib->creds, type, subtype,
156 BUILD_FROM_FILE, file, BUILD_END);
157 }
158 else
159 {
160 set_file_mode(stdin, CERT_ASN1_DER);
161 if (!chunk_from_fd(0, &chunk))
162 {
163 fprintf(stderr, "reading input failed: %s\n", strerror(errno));
164 return 1;
165 }
166 cred = lib->creds->create(lib->creds, type, subtype,
167 BUILD_BLOB, chunk, BUILD_END);
168 free(chunk.ptr);
169 }
170 if (!cred)
171 {
172 fprintf(stderr, "parsing input failed\n");
173 return 1;
174 }
175
176 if (type == CRED_CERTIFICATE)
177 {
178 certificate_t *cert = (certificate_t*)cred;
179 certificate_printer_t *printer;
180
181 printer = certificate_printer_create(stdout, TRUE, FALSE);
182 printer->print(printer, cert, FALSE);
183 printer->destroy(printer);
184 cert->destroy(cert);
185 }
186 if (type == CRED_PRIVATE_KEY)
187 {
188 private_key_t *key = (private_key_t*)cred;
189
190 print_key(key);
191 key->destroy(key);
192 }
193
194 return 0;
195 }
196
197 /**
198 * Register the command.
199 */
200 static void __attribute__ ((constructor))reg()
201 {
202 command_register((command_t)
203 { print, 'a', "print",
204 "print a credential in a human readable form",
205 {"[--in file|--keyid hex]",
206 "[--type x509|crl|ac|pub|priv|rsa|ecdsa|ed25519|ed448|bliss]"},
207 {
208 {"help", 'h', 0, "show usage information"},
209 {"in", 'i', 1, "input file, default: stdin"},
210 {"keyid", 'x', 1, "smartcard or TPM object handle"},
211 {"type", 't', 1, "type of credential, default: x509"},
212 }
213 });
214 }