3 crypto (Shishi
* handle
, struct arguments arg
)
9 arg
.cname
= shishi_principal_default (handle
);
11 if (arg
.crealm
== NULL
)
12 arg
.crealm
= shishi_realm_default (handle
);
16 char *cname
, *tok
, *tokptr
;
18 cname
= xstrdup (arg
.cname
);
19 arg
.salt
= xstrdup (arg
.crealm
);
20 tok
= strtok_r (cname
, "/", &tokptr
);
24 xrealloc (arg
.salt
, strlen (arg
.salt
) + strlen (tok
) + 1);
25 strcat (arg
.salt
, tok
);
26 tok
= strtok_r (NULL
, "/", &tokptr
);
31 rc
= shishi_key (handle
, &key
);
34 shishi_error_printf (handle
, _("Cannot create key: %s"),
35 shishi_strerror (rc
));
39 shishi_key_type_set (key
, arg
.algorithm
);
40 shishi_key_version_set (key
, arg
.kvno
);
41 shishi_key_principal_set (key
, arg
.cname
);
42 shishi_key_realm_set (key
, arg
.crealm
);
46 rc
= shishi_string_to_key (handle
, arg
.algorithm
,
48 strlen (arg
.password
),
50 strlen (arg
.salt
), arg
.parameter
, key
);
53 shishi_error_printf (handle
, _("Error in string2key"));
58 else if (arg
.keyvalue
)
60 rc
= shishi_key_from_base64 (handle
, arg
.algorithm
, arg
.keyvalue
, &key
);
63 fprintf (stderr
, _("Could not create key: %s\n"),
64 shishi_strerror (rc
));
72 rc
= shishi_randomize (handle
, 1, buf
,
73 shishi_cipher_randomlen (arg
.algorithm
));
77 shishi_random_to_key (handle
, arg
.algorithm
,
78 buf
, shishi_cipher_randomlen (arg
.algorithm
),
81 else if (arg
.readkeyfile
)
83 key
= shishi_keys_for_server_in_file (handle
, arg
.readkeyfile
,
86 shishi_key_from_file (handle
, arg
.writekeyfile
, arg
.algorithm
, key
,
87 keylen
, arg
.kvno
, arg
.cname
, arg
.realm
);
92 fprintf (stderr
, _("Could not find key: %s\n"),
93 shishi_error (handle
));
99 fprintf (stderr
, "Nothing to do.\n");
104 ((arg
.password
|| arg
.random
|| arg
.keyvalue
) &&
105 !(arg
.encrypt_p
|| arg
.decrypt_p
)))
107 shishi_key_print (handle
, stdout
, key
);
111 currently broken
if (arg
.encrypt_p
|| arg
.decrypt_p
)
115 infh
= fopen (arg
.inputfile
, "r");
118 shishi_error_printf (handle
, _("`%s': %s\n"),
119 arg
.inputfile
, strerror (errno
));
120 return SHISHI_FOPEN_ERROR
;
128 outfh
= fopen (arg
.outputfile
, "w");
131 shishi_error_printf (handle
, _("`%s': %s\n"),
132 arg
.inputfile
, strerror (errno
));
133 return SHISHI_FOPEN_ERROR
;
139 outlen
= fread (out
, sizeof (out
[0]),
140 sizeof (out
) / sizeof (out
[0]), infh
);
143 fprintf (stderr
, _("Error reading `%s'\n"), arg
.inputfile
);
147 printf (_("Read %d bytes...\n"), outlen
);
150 rc
= shishi_encrypt (handle
, key
, arg
.keyusage
,
151 out
, outlen
, &in
, &inlen
);
153 rc
= shishi_decrypt (handle
, key
, arg
.keyusage
,
154 in
, inlen
, &out
, &outlen
);
157 shishi_error_printf (handle
, _("Error ciphering\n"));
161 if (arg
.outputtype
== SHISHI_FILETYPE_HEX
)
163 for (i
= 0; i
< inlen
; i
++)
166 fprintf (outfh
, "\n");
167 fprintf (outfh
, "%02x ", in
[i
]);
169 fprintf (outfh
, "\n");
171 else if (arg
.outputtype
== SHISHI_FILETYPE_BINARY
)
173 i
= fwrite (in
, sizeof (in
[0]), inlen
, outfh
);
176 fprintf (stderr
, _("Short write (%d < %d)...\n"), i
, inlen
);
179 printf (_("Wrote %d bytes...\n"), inlen
);
187 shishi_error_printf (handle
, _("`%s': %s\n"),
188 arg
.outputfile
, strerror (errno
));
189 return SHISHI_FCLOSE_ERROR
;
198 shishi_error_printf (handle
, _("`%s': %s\n"),
199 arg
.inputfile
, strerror (errno
));
200 return SHISHI_FCLOSE_ERROR
;
206 if (arg
.writekeyfile
)
208 shishi_key_to_file (handle
, arg
.writekeyfile
, key
);
215 parse_filename (char *arg
, int *type
, char **var
)
217 if (strncasecmp (arg
, TYPE_TEXT_NAME
",", strlen (TYPE_TEXT_NAME
",")) == 0)
219 (*type
) = SHISHI_FILETYPE_TEXT
;
220 arg
+= strlen (TYPE_TEXT_NAME
",");
222 else if (strncasecmp (arg
, TYPE_DER_NAME
",", strlen (TYPE_DER_NAME
",")) ==
225 (*type
) = SHISHI_FILETYPE_DER
;
226 arg
+= strlen (TYPE_DER_NAME
",");
228 else if (strncasecmp (arg
, TYPE_HEX_NAME
",", strlen (TYPE_HEX_NAME
",")) ==
231 (*type
) = SHISHI_FILETYPE_HEX
;
232 arg
+= strlen (TYPE_HEX_NAME
",");
234 else if (strncasecmp (arg
, TYPE_BASE64_NAME
",",
235 strlen (TYPE_BASE64_NAME
",")) == 0)
237 (*type
) = SHISHI_FILETYPE_BASE64
;
238 arg
+= strlen (TYPE_BASE64_NAME
",");
240 else if (strncasecmp (arg
, TYPE_BINARY_NAME
",",
241 strlen (TYPE_BINARY_NAME
",")) == 0)
243 (*type
) = SHISHI_FILETYPE_BINARY
;
244 arg
+= strlen (TYPE_BINARY_NAME
",");
255 case OPTION_CRYPTO_ENCRYPT
:
256 arguments
->command
= OPTION_CRYPTO
;
257 if (arguments
->decrypt_p
)
258 argp_error (state
, _("Cannot both encrypt and decrypt."));
259 arguments
->encrypt_p
= 1;
262 case OPTION_CRYPTO_DECRYPT
:
263 arguments
->command
= OPTION_CRYPTO
;
264 if (arguments
->encrypt_p
)
265 argp_error (state
, _("Cannot both encrypt and decrypt."));
266 arguments
->decrypt_p
= 1;
269 case OPTION_CRYPTO_KEY_VALUE
:
270 arguments
->keyvalue
= strdup (arg
);
273 case OPTION_CRYPTO_KEY_USAGE
:
274 if (arguments
->command
!= OPTION_CRYPTO
)
275 argp_error (state
, _("Option `%s' only valid with CRYPTO."),
276 state
->argv
[state
->next
- 1]);
277 arguments
->keyusage
= atoi (arg
);
280 case OPTION_CRYPTO_KEY_VERSION
:
281 if (arguments
->command
!= OPTION_CRYPTO
)
282 argp_error (state
, _("Option `%s' only valid with CRYPTO."),
283 state
->argv
[state
->next
- 1]);
284 arguments
->kvno
= atoi (arg
);
287 case OPTION_CRYPTO_PARAMETER
:
288 if (arguments
->command
!= OPTION_CRYPTO
)
289 argp_error (state
, _("Option `%s' only valid with CRYPTO."),
290 state
->argv
[state
->next
- 1]);
291 arguments
->parameter
= strdup (arg
);
294 case OPTION_CRYPTO_PASSWORD
:
295 arguments
->password
= strdup (arg
);
298 case OPTION_CRYPTO_RANDOM
:
299 if (arguments
->command
!= OPTION_CRYPTO
)
300 argp_error (state
, _("Option `%s' only valid with CRYPTO."),
301 state
->argv
[state
->next
- 1]);
302 arguments
->random
= 1;
305 case OPTION_CRYPTO_READ_DATA_FILE
:
306 if (arguments
->command
!= OPTION_CRYPTO
)
307 argp_error (state
, _("Option `%s' only valid with CRYPTO."),
308 state
->argv
[state
->next
- 1]);
309 parse_filename (arg
, &arguments
->inputtype
, &arguments
->inputfile
);
310 if (arguments
->inputtype
== SHISHI_FILETYPE_TEXT
||
311 arguments
->inputtype
== SHISHI_FILETYPE_DER
)
312 arguments
->inputtype
= SHISHI_FILETYPE_BINARY
;
315 case OPTION_CRYPTO_READ_KEY_FILE
:
316 if (arguments
->command
!= OPTION_CRYPTO
)
317 argp_error (state
, _("Option `%s' only valid with CRYPTO."),
318 state
->argv
[state
->next
- 1]);
319 arguments
->readkeyfile
= strdup (arg
);
322 case OPTION_CRYPTO_SALT
:
323 if (arguments
->command
!= OPTION_CRYPTO
)
324 argp_error (state
, _("Option `%s' only valid with CRYPTO."),
325 state
->argv
[state
->next
- 1]);
326 arguments
->salt
= strdup (arg
);
329 case OPTION_CRYPTO_STR2KEY
:
330 arguments
->command
= OPTION_CRYPTO
;
333 if (arguments
->password
)
334 argp_error (state
, _("Password specified twice."));
335 arguments
->password
= strdup (arg
);
339 case OPTION_CRYPTO_WRITE_DATA_FILE
:
340 if (arguments
->command
!= OPTION_CRYPTO
)
341 argp_error (state
, _("Option `%s' only valid with CRYPTO."),
342 state
->argv
[state
->next
- 1]);
343 parse_filename (arg
, &arguments
->outputtype
, &arguments
->outputfile
);
344 if (arguments
->outputtype
== SHISHI_FILETYPE_TEXT
||
345 arguments
->outputtype
== SHISHI_FILETYPE_DER
)
346 arguments
->outputtype
= SHISHI_FILETYPE_BINARY
;
349 case OPTION_CRYPTO_WRITE_KEY_FILE
:
350 if (arguments
->command
!= OPTION_CRYPTO
)
351 argp_error (state
, _("Option `%s' only valid with CRYPTO."),
352 state
->argv
[state
->next
- 1]);
353 arguments
->writekeyfile
= strdup (arg
);
361 {"key-value", OPTION_CRYPTO_KEY_VALUE
, "KEY", 0,
362 "Cipher key to decrypt response (discouraged).", 0},
365 /************** CRYPTO */
368 "Options for low-level cryptography (CRYPTO-OPTIONS):", 100},
370 {"client-name", OPTION_CLIENT_NAME
, "NAME", 0,
371 "Username. Default is login name.", 0},
373 {"decrypt", OPTION_CRYPTO_DECRYPT
, 0, 0,
376 {"encrypt", OPTION_CRYPTO_ENCRYPT
, 0, 0,
379 {"key-usage", OPTION_CRYPTO_KEY_USAGE
, "KEYUSAGE", 0,
380 "Encrypt or decrypt using specified key usage. Default is 0, which "
381 "means no key derivation are performed.", 0},
383 {"key-value", OPTION_CRYPTO_KEY_VALUE
, "KEY", 0,
384 "Base64 encoded key value.", 0},
386 {"key-version", OPTION_CRYPTO_KEY_VERSION
, "INTEGER", 0,
387 "Version number of key. Default is 0.", 0},
389 {"random", OPTION_CRYPTO_RANDOM
, 0, 0,
390 "Generate key from random data.", 0},
392 {"read-key-file", OPTION_CRYPTO_READ_KEY_FILE
, "FILE", 0,
393 "Read cipher key from FILE", 0},
395 {"read-data-file", OPTION_CRYPTO_READ_DATA_FILE
, "[TYPE,]FILE", 0,
396 "Read data from FILE in TYPE, BASE64, HEX or BINARY (default).", 0},
398 {"realm", OPTION_REALM
, "REALM", 0,
399 "Realm of principal. Defaults to DNS domain of local host. ", 0},
401 {"salt", OPTION_CRYPTO_SALT
, "SALT", 0,
402 "Salt to use for --string-to-key. Defaults to concatenation of "
403 "realm and (unwrapped) client name.", 0},
405 {"string-to-key", OPTION_CRYPTO_STR2KEY
, "[PASSWORD]", OPTION_ARG_OPTIONAL
,
406 "Convert password into Kerberos key. Note that --client-name, --realm, "
407 "and --salt influence the generated key.", 0},
409 {"parameter", OPTION_CRYPTO_PARAMETER
, "STRING", 0,
410 "String-to-key parameter. This data is specific for each encryption "
411 "algorithm and rarely needed.", 0},
413 {"write-key-file", OPTION_CRYPTO_WRITE_KEY_FILE
, "FILE", 0,
414 "Append cipher key to FILE", 0},
416 {"write-data-file", OPTION_CRYPTO_WRITE_DATA_FILE
, "[TYPE,]FILE", 0,
417 "Write data to FILE in TYPE, BASE64, HEX or BINARY (default).", 0},
422 rc
= crypto (handle
, arg
);
424 fprintf (stderr
, "Operation failed:\n%s\n%s\n",
425 shishi_strerror (rc
), shishi_error (handle
));
429 else if (args
.list_flag
)
432 Shishi_tkts_hint hint
;
435 /* This doesn't work */
437 memset (&hint
, 0, sizeof (hint
));
439 hint
.server
= (sname
? sname
: args
.args
.ticket_granter_arg
);
440 hint
.starttime
= starttime
;
441 hint
.endtime
= endtime
;
442 hint
.renew_till
= renew_till
;
444 tkt
= shishi_tkts_find (shishi_tkts_default (sh
), &hint
);
447 fprintf (stderr
, "Could not get ticket for `%s'.\n", hint
.server
);
451 shishi_tkt_pretty_print (tkt
, stdout
);
453 /* Get ticket using TGT ... */
454 rc
= shishi_tgs (sh
, &tgs
);
455 shishi_tgs_tgtkt_set (tgs
, tkt
);
457 rc
= shishi_tgs_set_server (tgs
, hint
.server
);
458 rc
= shishi_kdcreq_options_add (sh
, shishi_tgs_req (tgs
),
459 SHISHI_KDCOPTIONS_RENEWABLE
|
460 SHISHI_KDCOPTIONS_RENEW
);
462 rc
= shishi_asn1_write (sh
, shishi_tgs_req (tgs
),
464 shishi_generalize_time
465 (sh
, hint
.renew_till
), 0);
467 rc
= shishi_tgs_req_build (tgs
);
469 rc
= shishi_tgs_sendrecv (tgs
);
471 rc
= shishi_tgs_rep_process (tgs
);
474 fprintf (stderr
, "TGS exchange failed: %s\n%s\n",
475 shishi_strerror (rc
), shishi_error (sh
));
476 if (rc
== SHISHI_GOT_KRBERROR
)
477 shishi_krberror_pretty_print (sh
, stdout
,
478 shishi_tgs_krberror (tgs
));
482 tkt
= shishi_tgs_tkt (tgs
);
485 fprintf (stderr
, "No ticket in TGS-REP?!: %s\n",
490 shishi_tkt_pretty_print (tkt
, stdout
);
492 rc
= shishi_tkts_add (shishi_tkts_default (sh
), tkt
);
494 fprintf (stderr
, "Could not add ticket: %s", shishi_strerror (rc
));