pki: Support absolute --not-before/after acert lifetimes
[strongswan.git] / src / pki / pki.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 #define _GNU_SOURCE
17 #include "command.h"
18 #include "pki.h"
19
20 #include <time.h>
21 #include <unistd.h>
22
23 #include <utils/debug.h>
24 #include <credentials/sets/callback_cred.h>
25
26 /**
27 * Convert a form string to a encoding type
28 */
29 bool get_form(char *form, cred_encoding_type_t *enc, credential_type_t type)
30 {
31 if (streq(form, "der"))
32 {
33 switch (type)
34 {
35 case CRED_CERTIFICATE:
36 *enc = CERT_ASN1_DER;
37 return TRUE;
38 case CRED_PRIVATE_KEY:
39 *enc = PRIVKEY_ASN1_DER;
40 return TRUE;
41 case CRED_PUBLIC_KEY:
42 /* der encoded keys usually contain the complete
43 * SubjectPublicKeyInfo */
44 *enc = PUBKEY_SPKI_ASN1_DER;
45 return TRUE;
46 default:
47 return FALSE;
48 }
49 }
50 else if (streq(form, "pem"))
51 {
52 switch (type)
53 {
54 case CRED_CERTIFICATE:
55 *enc = CERT_PEM;
56 return TRUE;
57 case CRED_PRIVATE_KEY:
58 *enc = PRIVKEY_PEM;
59 return TRUE;
60 case CRED_PUBLIC_KEY:
61 *enc = PUBKEY_PEM;
62 return TRUE;
63 default:
64 return FALSE;
65 }
66 }
67 else if (streq(form, "pgp"))
68 {
69 switch (type)
70 {
71 case CRED_PRIVATE_KEY:
72 *enc = PRIVKEY_PGP;
73 return TRUE;
74 case CRED_PUBLIC_KEY:
75 *enc = PUBKEY_PGP;
76 return TRUE;
77 default:
78 return FALSE;
79 }
80 }
81 else if (streq(form, "dnskey"))
82 {
83 switch (type)
84 {
85 case CRED_PUBLIC_KEY:
86 *enc = PUBKEY_DNSKEY;
87 return TRUE;
88 default:
89 return FALSE;
90 }
91 }
92 else if (streq(form, "sshkey"))
93 {
94 switch (type)
95 {
96 case CRED_PUBLIC_KEY:
97 *enc = PUBKEY_SSHKEY;
98 return TRUE;
99 default:
100 return FALSE;
101 }
102 }
103 return FALSE;
104 }
105
106 /**
107 * See header
108 */
109 bool calculate_lifetime(char *format, char *nbstr, char *nastr, time_t span,
110 time_t *nb, time_t *na)
111 {
112 struct tm tm;
113 time_t now;
114 char *end;
115
116 if (!format)
117 {
118 format = "%d.%m.%y %T";
119 }
120
121 now = time(NULL);
122
123 localtime_r(&now, &tm);
124 if (nbstr)
125 {
126 end = strptime(nbstr, format, &tm);
127 if (end == NULL || *end != '\0')
128 {
129 return FALSE;
130 }
131 }
132 *nb = mktime(&tm);
133
134 localtime_r(&now, &tm);
135 if (nastr)
136 {
137 end = strptime(nastr, format, &tm);
138 if (end == NULL || *end != '\0')
139 {
140 return FALSE;
141 }
142 }
143 *na = mktime(&tm);
144
145 if (!nbstr && nastr)
146 {
147 *nb = *na - span;
148 }
149 else if (!nastr)
150 {
151 *na = *nb + span;
152 }
153 return TRUE;
154 }
155
156 /**
157 * Callback credential set pki uses
158 */
159 static callback_cred_t *cb_set;
160
161 /**
162 * Callback function to receive credentials
163 */
164 static shared_key_t* cb(void *data, shared_key_type_t type,
165 identification_t *me, identification_t *other,
166 id_match_t *match_me, id_match_t *match_other)
167 {
168 char buf[64], *label, *secret;
169
170 switch (type)
171 {
172 case SHARED_PIN:
173 label = "Smartcard PIN";
174 break;
175 case SHARED_PRIVATE_KEY_PASS:
176 label = "Private key passphrase";
177 break;
178 default:
179 return NULL;
180 }
181 snprintf(buf, sizeof(buf), "%s: ", label);
182 secret = getpass(buf);
183 if (secret)
184 {
185 if (match_me)
186 {
187 *match_me = ID_MATCH_PERFECT;
188 }
189 if (match_other)
190 {
191 *match_other = ID_MATCH_NONE;
192 }
193 return shared_key_create(type,
194 chunk_clone(chunk_create(secret, strlen(secret))));
195 }
196 return NULL;
197 }
198
199 /**
200 * Register PIN/Passphrase callback function
201 */
202 static void add_callback()
203 {
204 cb_set = callback_cred_create_shared(cb, NULL);
205 lib->credmgr->add_set(lib->credmgr, &cb_set->set);
206 }
207
208 /**
209 * Unregister PIN/Passphrase callback function
210 */
211 static void remove_callback()
212 {
213 lib->credmgr->remove_set(lib->credmgr, &cb_set->set);
214 cb_set->destroy(cb_set);
215 }
216
217 /**
218 * Library initialization and operation parsing
219 */
220 int main(int argc, char *argv[])
221 {
222 atexit(library_deinit);
223 if (!library_init(NULL, "pki"))
224 {
225 exit(SS_RC_LIBSTRONGSWAN_INTEGRITY);
226 }
227 if (lib->integrity &&
228 !lib->integrity->check_file(lib->integrity, "pki", argv[0]))
229 {
230 fprintf(stderr, "integrity check of pki failed\n");
231 exit(SS_RC_DAEMON_INTEGRITY);
232 }
233 if (!lib->plugins->load(lib->plugins,
234 lib->settings->get_str(lib->settings, "pki.load", PLUGINS)))
235 {
236 exit(SS_RC_INITIALIZATION_FAILED);
237 }
238
239 add_callback();
240 atexit(remove_callback);
241 return command_dispatch(argc, argv);
242 }