05430675def5aed1f08213b4840976317e296ad7
[strongswan.git] / src / pki / commands / pub.c
1 /*
2 * Copyright (C) 2009 Martin Willi
3 * Hochschule fuer Technik Rapperswil
4 *
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License as published by the
7 * Free Software Foundation; either version 2 of the License, or (at your
8 * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
9 *
10 * This program is distributed in the hope that it will be useful, but
11 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
12 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
13 * for more details.
14 */
15
16 #include "pki.h"
17
18 #include <credentials/certificates/certificate.h>
19 #include <credentials/certificates/x509.h>
20
21 /**
22 * Extract a public key from a private key/certificate
23 */
24 static int pub(int argc, char *argv[])
25 {
26 key_encoding_type_t form = KEY_PUB_SPKI_ASN1_DER;
27 credential_type_t type = CRED_PRIVATE_KEY;
28 int subtype = KEY_RSA;
29 certificate_t *cert;
30 private_key_t *private;
31 public_key_t *public;
32 chunk_t encoding;
33 char *file = NULL;
34 void *cred;
35
36 while (TRUE)
37 {
38 switch (getopt_long(argc, argv, "", command_opts, NULL))
39 {
40 case 'h':
41 return command_usage(NULL);
42 case 'v':
43 dbg_level = atoi(optarg);
44 continue;
45 case 't':
46 if (streq(optarg, "rsa"))
47 {
48 type = CRED_PRIVATE_KEY;
49 subtype = KEY_RSA;
50 }
51 else if (streq(optarg, "ecdsa"))
52 {
53 type = CRED_PRIVATE_KEY;
54 subtype = KEY_ECDSA;
55 }
56 else if (streq(optarg, "pkcs10"))
57 {
58 type = CRED_CERTIFICATE;
59 subtype = CERT_PKCS10_REQUEST;
60 }
61 else if (streq(optarg, "x509"))
62 {
63 type = CRED_CERTIFICATE;
64 subtype = CERT_X509;
65 }
66 else
67 {
68 return command_usage("invalid input type");
69 }
70 continue;
71 case 'f':
72 if (!get_form(optarg, &form, TRUE))
73 {
74 return command_usage("invalid output format");
75 }
76 continue;
77 case 'i':
78 file = optarg;
79 continue;
80 case EOF:
81 break;
82 default:
83 return command_usage("invalid --pub option");
84 }
85 break;
86 }
87 if (file)
88 {
89 cred = lib->creds->create(lib->creds, type, subtype,
90 BUILD_FROM_FILE, file, BUILD_END);
91 }
92 else
93 {
94 cred = lib->creds->create(lib->creds, type, subtype,
95 BUILD_FROM_FD, 0, BUILD_END);
96 }
97
98 if (type == CRED_PRIVATE_KEY)
99 {
100 private = cred;
101 if (!private)
102 {
103 fprintf(stderr, "parsing private key failed\n");
104 return 1;
105 }
106 public = private->get_public_key(private);
107 private->destroy(private);
108 }
109 else
110 {
111 cert = cred;
112 if (!cert)
113 {
114 fprintf(stderr, "parsing certificate failed\n");
115 return 1;
116 }
117 public = cert->get_public_key(cert);
118 cert->destroy(cert);
119 }
120 if (!public)
121 {
122 fprintf(stderr, "extracting public key failed\n");
123 return 1;
124 }
125 if (!public->get_encoding(public, form, &encoding))
126 {
127 fprintf(stderr, "public key encoding failed\n");
128 public->destroy(public);
129 return 1;
130 }
131 public->destroy(public);
132 if (fwrite(encoding.ptr, encoding.len, 1, stdout) != 1)
133 {
134 fprintf(stderr, "writing public key failed\n");
135 free(encoding.ptr);
136 return 1;
137 }
138 free(encoding.ptr);
139 return 0;
140 }
141
142 /**
143 * Register the command.
144 */
145 static void __attribute__ ((constructor))reg()
146 {
147 command_register((command_t) {
148 pub, 'p', "pub",
149 "extract the public key from a private key/certificate",
150 {"[--in file] [--type rsa|ecdsa|pkcs10|x509] [--outform der|pem|pgp]",
151 "[--debug 0|1|2|3|4]"},
152 {
153 {"help", 'h', 0, "show usage information"},
154 {"in", 'i', 1, "input file, default: stdin"},
155 {"type", 't', 1, "type of credential, default: rsa"},
156 {"outform", 'f', 1, "encoding of extracted public key"},
157 {"debug", 'v', 1, "set debug level, default: 1"},
158 }
159 });
160 }
161