1 /* certreqgen-ui.c - Simple user interface for certreqgen.c
2 * Copyright (C) 2007 Free Software Foundation, Inc.
4 * This file is part of GnuPG.
6 * GnuPG is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 3 of the License, or
9 * (at your option) any later version.
11 * GnuPG is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, see <http://www.gnu.org/licenses/>.
37 /* Prompt for lines and append them to MB. */
39 ask_mb_lines (membuf_t
*mb
, const char *prefix
)
46 answer
= tty_get ("> ");
51 put_membuf_str (mb
, prefix
);
52 put_membuf_str (mb
, answer
);
53 put_membuf (mb
, "\n", 1);
60 /* Helper to store stuff in a membuf. */
62 store_key_value_lf (membuf_t
*mb
, const char *key
, const char *value
)
64 put_membuf_str (mb
, key
);
65 put_membuf_str (mb
, value
);
66 put_membuf (mb
, "\n", 1);
69 /* Helper tp store a membuf create by mb_ask_lines into MB. Returns
72 store_mb_lines (membuf_t
*mb
, membuf_t
*lines
)
76 if (get_membuf_len (lines
))
78 put_membuf (lines
, "", 1);
79 p
= get_membuf (lines
, NULL
);
82 put_membuf_str (mb
, p
);
89 /* This function is used to create a certificate request from the
90 command line. In the past the similar gpgsm-gencert.sh script has
91 been used for it; however that scripts requires a full Unix shell
92 and thus is not suitable for the Windows port. So here is the
95 gpgsm_gencertreq_tty (ctrl_t ctrl
, FILE *output_fp
)
103 char *keygrip
= NULL
;
108 const char *keyusage
;
110 membuf_t mb_email
, mb_dns
, mb_uri
, mb_result
;
115 init_membuf (&mb_email
, 100);
116 init_membuf (&mb_dns
, 100);
117 init_membuf (&mb_uri
, 100);
118 init_membuf (&mb_result
, 512);
120 /* Get the type of the key. */
121 tty_printf (_("Please select what kind of key you want:\n"));
122 tty_printf (_(" (%d) RSA\n"), 1 );
123 tty_printf (_(" (%d) Existing key\n"), 2 );
124 tty_printf (_(" (%d) Existing key from card\n"), 3 );
128 answer
= tty_get (_("Your selection? "));
130 selection
= *answer
? atoi (answer
): 1;
133 while (!(selection
>= 1 && selection
<= 3));
136 /* Get size of the key. */
139 keytype
= xstrdup ("RSA");
142 answer
= tty_getf (_("What keysize do you want? (%u) "), defbits
);
144 nbits
= *answer
? atoi (answer
): defbits
;
146 if (nbits
< minbits
|| nbits
> maxbits
)
147 tty_printf(_("%s keysizes must be in the range %u-%u\n"),
148 "RSA", minbits
, maxbits
);
152 tty_printf (_("Requested keysize is %u bits\n"), nbits
);
153 /* We round it up so that it better matches the word size. */
156 nbits
= ((nbits
+ 63) / 64) * 64;
157 tty_printf (_("rounded up to %u bits\n"), nbits
);
160 else if (method
== 2)
162 tty_printf ("Not yet supported; "
163 "use the gpgsm-gencert.sh script instead\n");
164 keytype
= xstrdup ("RSA");
165 nbits
= defbits
; /* We need a dummy value. */
167 else /* method == 3 */
169 tty_printf ("Not yet supported; "
170 "use the gpgsm-gencert.sh script instead\n");
171 keytype
= xstrdup ("card:foobar");
172 nbits
= defbits
; /* We need a dummy value. */
175 /* Ask for the key usage. */
176 tty_printf (_("Possible actions for a %s key:\n"), "RSA");
177 tty_printf (_(" (%d) sign, encrypt\n"), 1 );
178 tty_printf (_(" (%d) sign\n"), 2 );
179 tty_printf (_(" (%d) encrypt\n"), 3 );
182 answer
= tty_get (_("Your selection? "));
184 selection
= *answer
? atoi (answer
): 1;
188 case 1: keyusage
= "sign, encrypt"; break;
189 case 2: keyusage
= "sign"; break;
190 case 3: keyusage
= "encrypt"; break;
191 default: keyusage
= NULL
; break;
196 /* Get the subject name. */
200 size_t erroff
, errlen
;
203 answer
= tty_get (_("Enter the X.509 subject name: "));
205 trim_spaces (answer
);
207 tty_printf (_("No subject name given\n"));
208 else if ( (err
= ksba_dn_teststr (answer
, 0, &erroff
, &errlen
)) )
210 if (gpg_err_code (err
) == GPG_ERR_UNKNOWN_NAME
)
211 tty_printf (_("Invalid subject name label `%.*s'\n"),
212 (int)errlen
, answer
+erroff
);
215 /* TRANSLATORS: The 22 in the second string is the
216 length of the first string up to the "%s". Please
217 adjust it do the length of your translation. The
218 second string is merely passed to atoi so you can
219 drop everything after the number. */
220 tty_printf (_("Invalid subject name `%s'\n"), answer
);
221 tty_printf ("%*s^\n",
222 atoi (_("22 translator: see "
223 "certreg-ui.c:gpgsm_gencertreq_tty"))
230 subject_name
= answer
;
233 /* Get the email addresses. */
234 tty_printf (_("Enter email addresses"));
235 tty_printf (_(" (end with an empty line):\n"));
236 ask_mb_lines (&mb_email
, "Name-Email: ");
239 tty_printf (_("Enter DNS names"));
240 tty_printf (_(" (optional; end with an empty line):\n"));
241 ask_mb_lines (&mb_email
, "Name-DNS: ");
244 tty_printf (_("Enter URIs"));
245 tty_printf (_(" (optional; end with an empty line):\n"));
246 ask_mb_lines (&mb_email
, "Name-URI: ");
249 /* Put it all together. */
250 store_key_value_lf (&mb_result
, "Key-Type: ", keytype
);
253 snprintf (numbuf
, sizeof numbuf
, "%u", nbits
);
254 store_key_value_lf (&mb_result
, "Key-Length: ", numbuf
);
256 store_key_value_lf (&mb_result
, "Key-Usage: ", keyusage
);
257 store_key_value_lf (&mb_result
, "Name-DN: ", subject_name
);
259 store_key_value_lf (&mb_result
, "Key-Grip: ", keygrip
);
260 if (store_mb_lines (&mb_result
, &mb_email
))
262 if (store_mb_lines (&mb_result
, &mb_dns
))
264 if (store_mb_lines (&mb_result
, &mb_uri
))
266 put_membuf (&mb_result
, "", 1);
267 result
= get_membuf (&mb_result
, NULL
);
271 tty_printf (_("Parameters to be used for the certificate request:\n"));
272 for (s
=result
; (s2
= strchr (s
, '\n')); s
= s2
+1, i
++)
273 tty_printf (" %.*s\n", (int)(s2
-s
), s
);
277 if (!tty_get_answer_is_yes ("Really create request? (y/N) "))
280 /* Now create a parameter file and generate the key. */
281 fp
= es_fopenmem (0, "w+");
284 log_error (_("error creating temporary file: %s\n"), strerror (errno
));
287 es_fputs (result
, fp
);
289 tty_printf (_("Now creating certificate request. "
290 "This may take a while ...\n"));
292 int save_pem
= ctrl
->create_pem
;
293 ctrl
->create_pem
= 1; /* Force creation of PEM. */
294 err
= gpgsm_genkey (ctrl
, fp
, output_fp
);
295 ctrl
->create_pem
= save_pem
;
298 tty_printf (_("Ready. You should now send this request to your CA.\n"));
303 log_error (_("resource problem: out of core\n"));
307 xfree (subject_name
);
309 xfree (get_membuf (&mb_email
, NULL
));
310 xfree (get_membuf (&mb_dns
, NULL
));
311 xfree (get_membuf (&mb_uri
, NULL
));
312 xfree (get_membuf (&mb_result
, NULL
));