Do not query for CKA_ALWAYS_AUTHENTICATE if PKCS#11 Cryptoki version < 2.20
[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()
25 {
26 cred_encoding_type_t form = PUBKEY_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, *keyid = NULL;
34 void *cred;
35 char *arg;
36
37 while (TRUE)
38 {
39 switch (command_getopt(&arg))
40 {
41 case 'h':
42 return command_usage(NULL);
43 case 't':
44 if (streq(arg, "rsa"))
45 {
46 type = CRED_PRIVATE_KEY;
47 subtype = KEY_RSA;
48 }
49 else if (streq(arg, "ecdsa"))
50 {
51 type = CRED_PRIVATE_KEY;
52 subtype = KEY_ECDSA;
53 }
54 else if (streq(arg, "pkcs10"))
55 {
56 type = CRED_CERTIFICATE;
57 subtype = CERT_PKCS10_REQUEST;
58 }
59 else if (streq(arg, "x509"))
60 {
61 type = CRED_CERTIFICATE;
62 subtype = CERT_X509;
63 }
64 else
65 {
66 return command_usage("invalid input type");
67 }
68 continue;
69 case 'f':
70 if (!get_form(arg, &form, CRED_PUBLIC_KEY))
71 {
72 return command_usage("invalid output format");
73 }
74 continue;
75 case 'i':
76 file = arg;
77 continue;
78 case 'x':
79 keyid = arg;
80 continue;
81 case EOF:
82 break;
83 default:
84 return command_usage("invalid --pub option");
85 }
86 break;
87 }
88 if (file)
89 {
90 cred = lib->creds->create(lib->creds, type, subtype,
91 BUILD_FROM_FILE, file, BUILD_END);
92 }
93 else if (keyid)
94 {
95 chunk_t chunk;
96
97 chunk = chunk_from_hex(chunk_create(keyid, strlen(keyid)), NULL);
98 cred = lib->creds->create(lib->creds, CRED_PRIVATE_KEY, KEY_ANY,
99 BUILD_PKCS11_KEYID, chunk, BUILD_END);
100 free(chunk.ptr);
101 }
102 else
103 {
104 cred = lib->creds->create(lib->creds, type, subtype,
105 BUILD_FROM_FD, 0, BUILD_END);
106 }
107
108 if (type == CRED_PRIVATE_KEY)
109 {
110 private = cred;
111 if (!private)
112 {
113 fprintf(stderr, "parsing private key failed\n");
114 return 1;
115 }
116 public = private->get_public_key(private);
117 private->destroy(private);
118 }
119 else
120 {
121 cert = cred;
122 if (!cert)
123 {
124 fprintf(stderr, "parsing certificate failed\n");
125 return 1;
126 }
127 public = cert->get_public_key(cert);
128 cert->destroy(cert);
129 }
130 if (!public)
131 {
132 fprintf(stderr, "extracting public key failed\n");
133 return 1;
134 }
135 if (!public->get_encoding(public, form, &encoding))
136 {
137 fprintf(stderr, "public key encoding failed\n");
138 public->destroy(public);
139 return 1;
140 }
141 public->destroy(public);
142 if (fwrite(encoding.ptr, encoding.len, 1, stdout) != 1)
143 {
144 fprintf(stderr, "writing public key failed\n");
145 free(encoding.ptr);
146 return 1;
147 }
148 free(encoding.ptr);
149 return 0;
150 }
151
152 /**
153 * Register the command.
154 */
155 static void __attribute__ ((constructor))reg()
156 {
157 command_register((command_t) {
158 pub, 'p', "pub",
159 "extract the public key from a private key/certificate",
160 {"[--in file|--keyid hex] [--type rsa|ecdsa|pkcs10|x509]",
161 "[--outform der|pem|pgp]"},
162 {
163 {"help", 'h', 0, "show usage information"},
164 {"in", 'i', 1, "input file, default: stdin"},
165 {"keyid", 'x', 1, "keyid on smartcard of private key"},
166 {"type", 't', 1, "type of credential, default: rsa"},
167 {"outform", 'f', 1, "encoding of extracted public key"},
168 }
169 });
170 }
171