2 * Copyright (C) 2009 Martin Willi
3 * Hochschule fuer Technik Rapperswil
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>.
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
24 #include <utils/debug.h>
25 #include <credentials/sets/callback_cred.h>
28 * Convert a form string to a encoding type
30 bool get_form(char *form
, cred_encoding_type_t
*enc
, credential_type_t type
)
32 if (streq(form
, "der"))
36 case CRED_CERTIFICATE
:
39 case CRED_PRIVATE_KEY
:
40 *enc
= PRIVKEY_ASN1_DER
;
43 /* der encoded keys usually contain the complete
44 * SubjectPublicKeyInfo */
45 *enc
= PUBKEY_SPKI_ASN1_DER
;
51 else if (streq(form
, "pem"))
55 case CRED_CERTIFICATE
:
58 case CRED_PRIVATE_KEY
:
68 else if (streq(form
, "pgp"))
72 case CRED_PRIVATE_KEY
:
82 else if (streq(form
, "dnskey"))
93 else if (streq(form
, "sshkey"))
108 * Convert a time string to struct tm using strptime format
110 static bool convert_time(char *str
, char *format
, struct tm
*tm
)
118 format
= "%d.%m.%y %T";
121 end
= strptime(str
, format
, tm
);
122 if (end
== NULL
|| *end
!= '\0')
128 #else /* !HAVE_STRPTIME */
132 fprintf(stderr
, "custom datetime string format not supported\n");
136 if (sscanf(str
, "%d.%d.%d %d:%d:%d",
137 &tm
->tm_mday
, &tm
->tm_mon
, &tm
->tm_year
,
138 &tm
->tm_hour
, &tm
->tm_min
, &tm
->tm_sec
) != 6)
142 /* strptime() interprets two-digit years > 68 as 19xx, do the same here.
143 * mktime() expects years based on 1900 */
144 if (tm
->tm_year
<= 68)
148 else if (tm
->tm_year
>= 1900)
149 { /* looks like four digits? */
152 /* month is specified from 0-11 */
154 /* automatically detect daylight saving time */
158 #endif /* !HAVE_STRPTIME */
164 bool calculate_lifetime(char *format
, char *nbstr
, char *nastr
, time_t span
,
165 time_t *nb
, time_t *na
)
172 localtime_r(&now
, &tm
);
175 if (!convert_time(nbstr
, format
, &tm
))
186 localtime_r(&now
, &tm
);
189 if (!convert_time(nastr
, format
, &tm
))
212 * Set output file mode appropriate for credential encoding form on Windows
214 void set_file_mode(FILE *stream
, cred_encoding_type_t enc
)
224 /* keep default text mode */
227 /* switch to binary mode */
233 _setmode(fd
, _O_BINARY
);
239 * Callback credential set pki uses
241 static callback_cred_t
*cb_set
;
244 * Callback function to receive credentials
246 static shared_key_t
* cb(void *data
, shared_key_type_t type
,
247 identification_t
*me
, identification_t
*other
,
248 id_match_t
*match_me
, id_match_t
*match_other
)
250 char buf
[64], *label
, *secret
= NULL
;
255 label
= "Smartcard PIN";
257 case SHARED_PRIVATE_KEY_PASS
:
258 label
= "Private key passphrase";
263 snprintf(buf
, sizeof(buf
), "%s: ", label
);
265 secret
= getpass(buf
);
267 if (secret
&& strlen(secret
))
271 *match_me
= ID_MATCH_PERFECT
;
275 *match_other
= ID_MATCH_NONE
;
277 return shared_key_create(type
,
278 chunk_clone(chunk_create(secret
, strlen(secret
))));
284 * Register PIN/Passphrase callback function
286 static void add_callback()
288 cb_set
= callback_cred_create_shared(cb
, NULL
);
289 lib
->credmgr
->add_set(lib
->credmgr
, &cb_set
->set
);
293 * Unregister PIN/Passphrase callback function
295 static void remove_callback()
297 lib
->credmgr
->remove_set(lib
->credmgr
, &cb_set
->set
);
298 cb_set
->destroy(cb_set
);
302 * Library initialization and operation parsing
304 int main(int argc
, char *argv
[])
306 atexit(library_deinit
);
307 if (!library_init(NULL
, "pki"))
309 exit(SS_RC_LIBSTRONGSWAN_INTEGRITY
);
311 if (lib
->integrity
&&
312 !lib
->integrity
->check_file(lib
->integrity
, "pki", argv
[0]))
314 fprintf(stderr
, "integrity check of pki failed\n");
315 exit(SS_RC_DAEMON_INTEGRITY
);
317 if (!lib
->plugins
->load(lib
->plugins
,
318 lib
->settings
->get_str(lib
->settings
, "pki.load", PLUGINS
)))
320 exit(SS_RC_INITIALIZATION_FAILED
);
324 atexit(remove_callback
);
325 return command_dispatch(argc
, argv
);