Annotation of embedaddon/strongswan/src/pki/commands/req.c, revision 1.1.1.1
1.1 misho 1: /*
2: * Copyright (C) 2009 Martin Willi
3: * Copyright (C) 2009-2017 Andreas Steffen
4: * HSR Hochschule fuer Technik Rapperswil
5: *
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>.
10: *
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
14: * for more details.
15: */
16:
17: #include <time.h>
18: #include <errno.h>
19:
20: #include "pki.h"
21:
22: #include <collections/linked_list.h>
23: #include <credentials/certificates/certificate.h>
24:
25: /**
26: * Create a self-signed PKCS#10 certificate request.
27: */
28: static int req()
29: {
30: cred_encoding_type_t form = CERT_ASN1_DER;
31: key_type_t type = KEY_ANY;
32: hash_algorithm_t digest = HASH_UNKNOWN;
33: signature_params_t *scheme = NULL;
34: certificate_t *cert = NULL;
35: private_key_t *private = NULL;
36: char *file = NULL, *keyid = NULL, *dn = NULL, *error = NULL;
37: identification_t *id = NULL;
38: linked_list_t *san;
39: chunk_t encoding = chunk_empty;
40: chunk_t challenge_password = chunk_empty;
41: char *arg;
42: bool pss = lib->settings->get_bool(lib->settings, "%s.rsa_pss", FALSE,
43: lib->ns);
44:
45: san = linked_list_create();
46:
47: while (TRUE)
48: {
49: switch (command_getopt(&arg))
50: {
51: case 'h':
52: goto usage;
53: case 't':
54: if (streq(arg, "rsa"))
55: {
56: type = KEY_RSA;
57: }
58: else if (streq(arg, "ecdsa"))
59: {
60: type = KEY_ECDSA;
61: }
62: else if (streq(arg, "bliss"))
63: {
64: type = KEY_BLISS;
65: }
66: else if (streq(arg, "priv"))
67: {
68: type = KEY_ANY;
69: }
70: else
71: {
72: error = "invalid input type";
73: goto usage;
74: }
75: continue;
76: case 'g':
77: if (!enum_from_name(hash_algorithm_short_names, arg, &digest))
78: {
79: error = "invalid --digest type";
80: goto usage;
81: }
82: continue;
83: case 'R':
84: if (streq(arg, "pss"))
85: {
86: pss = TRUE;
87: }
88: else if (!streq(arg, "pkcs1"))
89: {
90: error = "invalid RSA padding";
91: goto usage;
92: }
93: continue;
94: case 'i':
95: file = arg;
96: continue;
97: case 'd':
98: dn = arg;
99: continue;
100: case 'a':
101: san->insert_last(san, identification_create_from_string(arg));
102: continue;
103: case 'p':
104: challenge_password = chunk_create(arg, strlen(arg));
105: continue;
106: case 'f':
107: if (!get_form(arg, &form, CRED_CERTIFICATE))
108: {
109: error = "invalid output format";
110: goto usage;
111: }
112: continue;
113: case 'x':
114: keyid = arg;
115: continue;
116: case EOF:
117: break;
118: default:
119: error = "invalid --req option";
120: goto usage;
121: }
122: break;
123: }
124:
125: if (!dn)
126: {
127: error = "--dn is required";
128: goto usage;
129: }
130: id = identification_create_from_string(dn);
131: if (id->get_type(id) != ID_DER_ASN1_DN)
132: {
133: error = "supplied --dn is not a distinguished name";
134: goto end;
135: }
136: if (file)
137: {
138: private = lib->creds->create(lib->creds, CRED_PRIVATE_KEY, type,
139: BUILD_FROM_FILE, file, BUILD_END);
140: }
141: else if (keyid)
142: {
143: chunk_t chunk;
144:
145: chunk = chunk_from_hex(chunk_create(keyid, strlen(keyid)), NULL);
146: private = lib->creds->create(lib->creds, CRED_PRIVATE_KEY, KEY_ANY,
147: BUILD_PKCS11_KEYID, chunk, BUILD_END);
148: free(chunk.ptr);
149: }
150: else
151: {
152: chunk_t chunk;
153:
154: set_file_mode(stdin, CERT_ASN1_DER);
155: if (!chunk_from_fd(0, &chunk))
156: {
157: fprintf(stderr, "reading private key failed: %s\n", strerror(errno));
158: error = "";
159: goto end;
160: }
161: private = lib->creds->create(lib->creds, CRED_PRIVATE_KEY, type,
162: BUILD_BLOB, chunk, BUILD_END);
163: free(chunk.ptr);
164: }
165: if (!private)
166: {
167: error = "parsing private key failed";
168: goto end;
169: }
170: scheme = get_signature_scheme(private, digest, pss);
171: if (!scheme)
172: {
173: error = "no signature scheme found";
174: goto end;
175: }
176:
177: cert = lib->creds->create(lib->creds, CRED_CERTIFICATE, CERT_PKCS10_REQUEST,
178: BUILD_SIGNING_KEY, private,
179: BUILD_SUBJECT, id,
180: BUILD_SUBJECT_ALTNAMES, san,
181: BUILD_CHALLENGE_PWD, challenge_password,
182: BUILD_SIGNATURE_SCHEME, scheme,
183: BUILD_END);
184: if (!cert)
185: {
186: error = "generating certificate request failed";
187: goto end;
188: }
189: if (!cert->get_encoding(cert, form, &encoding))
190: {
191: error = "encoding certificate request failed";
192: goto end;
193: }
194: set_file_mode(stdout, form);
195: if (fwrite(encoding.ptr, encoding.len, 1, stdout) != 1)
196: {
197: error = "writing certificate request failed";
198: goto end;
199: }
200:
201: end:
202: DESTROY_IF(id);
203: DESTROY_IF(cert);
204: DESTROY_IF(private);
205: san->destroy_offset(san, offsetof(identification_t, destroy));
206: signature_params_destroy(scheme);
207: free(encoding.ptr);
208:
209: if (error)
210: {
211: fprintf(stderr, "%s\n", error);
212: return 1;
213: }
214: return 0;
215:
216: usage:
217: san->destroy_offset(san, offsetof(identification_t, destroy));
218: return command_usage(error);
219: }
220:
221: /**
222: * Register the command.
223: */
224: static void __attribute__ ((constructor))reg()
225: {
226: command_register((command_t) {
227: req, 'r', "req",
228: "create a PKCS#10 certificate request",
229: {"[--in file|--keyid hex] [--type rsa|ecdsa|bliss|priv] --dn distinguished-name",
230: "[--san subjectAltName]+ [--password challengePassword]",
231: "[--digest md5|sha1|sha224|sha256|sha384|sha512|sha3_224|sha3_256|sha3_384|sha3_512]",
232: "[--rsa-padding pkcs1|pss]",
233: "[--outform der|pem]"},
234: {
235: {"help", 'h', 0, "show usage information"},
236: {"in", 'i', 1, "private key input file, default: stdin"},
237: {"keyid", 'x', 1, "smartcard or TPM private key object handle"},
238: {"type", 't', 1, "type of input key, default: priv"},
239: {"dn", 'd', 1, "subject distinguished name"},
240: {"san", 'a', 1, "subjectAltName to include in cert request"},
241: {"password", 'p', 1, "challengePassword to include in cert request"},
242: {"digest", 'g', 1, "digest for signature creation, default: key-specific"},
243: {"rsa-padding", 'R', 1, "padding for RSA signatures, default: pkcs1"},
244: {"outform", 'f', 1, "encoding of generated request, default: der"},
245: }
246: });
247: }
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>