2 * Copyright (C) 2009 Martin Willi
3 * Copyright (C) 2015 Andreas Steffen
4 * HSR Hochschule fuer Technik Rapperswil
6 * This program is free software; you can redistribute it and/or modify it
7 * under the terms of the GNU General Public License as published by the
8 * Free Software Foundation; either version 2 of the License, or (at your
9 * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
11 * This program is distributed in the hope that it will be useful, but
12 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
13 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
21 #include <credentials/certificates/certificate.h>
22 #include <credentials/certificates/x509.h>
25 * Extract a public key from a private key/certificate
29 cred_encoding_type_t form
= PUBKEY_SPKI_ASN1_DER
;
30 credential_type_t type
= CRED_PRIVATE_KEY
;
31 int subtype
= KEY_ANY
;
33 private_key_t
*private;
36 char *file
= NULL
, *keyid
= NULL
;
42 switch (command_getopt(&arg
))
45 return command_usage(NULL
);
47 if (streq(arg
, "rsa"))
49 type
= CRED_PRIVATE_KEY
;
52 else if (streq(arg
, "ecdsa"))
54 type
= CRED_PRIVATE_KEY
;
57 else if (streq(arg
, "bliss"))
59 type
= CRED_PRIVATE_KEY
;
62 else if (streq(arg
, "priv"))
64 type
= CRED_PRIVATE_KEY
;
67 else if (streq(arg
, "pub"))
69 type
= CRED_PUBLIC_KEY
;
72 else if (streq(arg
, "pkcs10"))
74 type
= CRED_CERTIFICATE
;
75 subtype
= CERT_PKCS10_REQUEST
;
77 else if (streq(arg
, "x509"))
79 type
= CRED_CERTIFICATE
;
84 return command_usage("invalid input type");
88 if (!get_form(arg
, &form
, CRED_PUBLIC_KEY
))
90 return command_usage("invalid output format");
102 return command_usage("invalid --pub option");
108 cred
= lib
->creds
->create(lib
->creds
, type
, subtype
,
109 BUILD_FROM_FILE
, file
, BUILD_END
);
115 chunk
= chunk_from_hex(chunk_create(keyid
, strlen(keyid
)), NULL
);
116 cred
= lib
->creds
->create(lib
->creds
, CRED_PRIVATE_KEY
, KEY_ANY
,
117 BUILD_PKCS11_KEYID
, chunk
, BUILD_END
);
124 set_file_mode(stdin
, CERT_ASN1_DER
);
125 if (!chunk_from_fd(0, &chunk
))
127 fprintf(stderr
, "reading input failed: %s\n", strerror(errno
));
130 cred
= lib
->creds
->create(lib
->creds
, type
, subtype
,
131 BUILD_BLOB
, chunk
, BUILD_END
);
135 if (type
== CRED_PRIVATE_KEY
)
140 fprintf(stderr
, "parsing private key failed\n");
143 public = private->get_public_key(private);
144 private->destroy(private);
146 else if (type
== CRED_PUBLIC_KEY
)
151 fprintf(stderr
, "parsing public key failed\n");
160 fprintf(stderr
, "parsing certificate failed\n");
163 public = cert
->get_public_key(cert
);
168 fprintf(stderr
, "extracting public key failed\n");
171 if (!public->get_encoding(public, form
, &encoding
))
173 fprintf(stderr
, "public key encoding failed\n");
174 public->destroy(public);
177 public->destroy(public);
178 set_file_mode(stdout
, form
);
179 if (fwrite(encoding
.ptr
, encoding
.len
, 1, stdout
) != 1)
181 fprintf(stderr
, "writing public key failed\n");
190 * Register the command.
192 static void __attribute__ ((constructor
))reg()
194 command_register((command_t
) {
196 "extract the public key from a private key/certificate",
197 {"[--in file|--keyid hex] [--type rsa|ecdsa|bliss|priv|pub|pkcs10|x509]",
198 "[--outform der|pem|dnskey|sshkey]"},
200 {"help", 'h', 0, "show usage information"},
201 {"in", 'i', 1, "input file, default: stdin"},
202 {"keyid", 'x', 1, "keyid on smartcard of private key"},
203 {"type", 't', 1, "type of credential, default: priv"},
204 {"outform", 'f', 1, "encoding of extracted public key, default: der"},