... | ... |
@@ -65,7 +65,6 @@ static int w_stirshaken_check_identity_with_key(sip_msg_t *msg, char *pkey_path, |
65 | 65 |
static int w_stirshaken_add_identity(sip_msg_t *msg, str *px5u, str *pattest, str *porigtn_val, str *pdesttn_val, str *porigid); |
66 | 66 |
static int w_stirshaken_add_identity_with_key(sip_msg_t *msg, str *px5u, str *pattest, str *porigtn_val, str *pdesttn_val, str *porigid, str *pkeypath); |
67 | 67 |
|
68 |
- |
|
69 | 68 |
/* clang-format off */ |
70 | 69 |
static cmd_export_t cmds[]={ |
71 | 70 |
{"stirshaken_check_identity", (cmd_function)w_stirshaken_check_identity, 0, |
... | ... |
@@ -158,6 +157,96 @@ static int get_cert_name_hashed(const char *name, char *buf, int buf_len) |
158 | 157 |
return 0; |
159 | 158 |
} |
160 | 159 |
|
160 |
+static int stirshaken_handle_cache_to_disk(X509 *x, STACK_OF(X509) *xchain, const char *cert_full_path) |
|
161 |
+{ |
|
162 |
+ int i = 0; |
|
163 |
+ int w = 0; |
|
164 |
+ FILE *fp = NULL; |
|
165 |
+ X509 *xc = NULL; |
|
166 |
+ |
|
167 |
+ if (!x) { |
|
168 |
+ LM_ERR("Refusing to save an empty cert\n"); |
|
169 |
+ return -1; |
|
170 |
+ } |
|
171 |
+ |
|
172 |
+ fp = fopen(cert_full_path, "w"); |
|
173 |
+ if (!fp) { |
|
174 |
+ LM_ERR("Failed to create file: %s", cert_full_path); |
|
175 |
+ return -1; |
|
176 |
+ } |
|
177 |
+ |
|
178 |
+ w = PEM_write_X509(fp, x); |
|
179 |
+ if (w == 0) { |
|
180 |
+ LM_ERR("Failed to write cert to %s", cert_full_path); |
|
181 |
+ goto fail; |
|
182 |
+ } |
|
183 |
+ |
|
184 |
+ for (i = 0; i < sk_X509_num(xchain); i++) { |
|
185 |
+ xc = sk_X509_value(xchain, i); |
|
186 |
+ if (!xc) continue; |
|
187 |
+ w = PEM_write_X509(fp, xc); |
|
188 |
+ if (w == 0) { |
|
189 |
+ LM_ERR("Failed to write chain to %s", cert_full_path); |
|
190 |
+ goto fail; |
|
191 |
+ } |
|
192 |
+ } |
|
193 |
+ |
|
194 |
+ if (fp) fclose(fp); |
|
195 |
+ fp = NULL; |
|
196 |
+ |
|
197 |
+ return 0; |
|
198 |
+ |
|
199 |
+fail: |
|
200 |
+ if (fp) fclose(fp); |
|
201 |
+ return -1; |
|
202 |
+} |
|
203 |
+ |
|
204 |
+static int stirshaken_handle_cache_from_disk(stir_shaken_context_t *ss, stir_shaken_cert_t *cert, const char *name) |
|
205 |
+{ |
|
206 |
+ FILE *fp = NULL; |
|
207 |
+ X509 *wcert = NULL; |
|
208 |
+ |
|
209 |
+ LM_DBG("Handle cache from disk; %s", name); |
|
210 |
+ |
|
211 |
+ if (stir_shaken_zstr(name)) { |
|
212 |
+ LM_ERR("Cert file name missing"); |
|
213 |
+ return -1; |
|
214 |
+ } |
|
215 |
+ |
|
216 |
+ fp = fopen(name, "r"); |
|
217 |
+ if (!fp) { |
|
218 |
+ LM_ERR("Failed to open %s: %s", name, strerror(errno)); |
|
219 |
+ goto fail; |
|
220 |
+ } |
|
221 |
+ |
|
222 |
+ cert->xchain = sk_X509_new_null(); |
|
223 |
+ |
|
224 |
+ while ((wcert = PEM_read_X509(fp, NULL, NULL, NULL))) { |
|
225 |
+ if (!cert->x) { |
|
226 |
+ cert->x = wcert; |
|
227 |
+ } |
|
228 |
+ else { |
|
229 |
+ sk_X509_push(cert->xchain, wcert); |
|
230 |
+ } |
|
231 |
+ } |
|
232 |
+ |
|
233 |
+ LM_DBG("done reading file, got %d certs and %d chains", cert->x ? 1 : 0, sk_X509_num(cert->xchain)); |
|
234 |
+ |
|
235 |
+ if (!cert->x) { |
|
236 |
+ LM_ERR("No certificate found in %s", name); |
|
237 |
+ goto fail; |
|
238 |
+ } |
|
239 |
+ |
|
240 |
+ if (fp) fclose(fp); |
|
241 |
+ fp = NULL; |
|
242 |
+ |
|
243 |
+ return 0; |
|
244 |
+ |
|
245 |
+fail: |
|
246 |
+ if (fp) fclose(fp); |
|
247 |
+ return -1; |
|
248 |
+} |
|
249 |
+ |
|
161 | 250 |
static stir_shaken_status_t shaken_callback(stir_shaken_callback_arg_t *arg) |
162 | 251 |
{ |
163 | 252 |
stir_shaken_context_t ss = { 0 }; |
... | ... |
@@ -207,18 +296,18 @@ static stir_shaken_status_t shaken_callback(stir_shaken_callback_arg_t *arg) |
207 | 296 |
|
208 | 297 |
diff = now_s - attr.st_mtime; |
209 | 298 |
|
210 |
- LM_DBG("Checking cached certificate against expiration setting of %zus (now is: %zu, file modification timestamp is: %zu, difference is: %zu)\n", |
|
299 |
+ LM_DBG("Checking cached certificate against expiration setting of %zus (now is: %lu, file modification timestamp is: %lu, difference is: %lu)\n", |
|
211 | 300 |
stirshaken_vs_cache_expire_s, now_s, attr.st_mtime, diff); |
212 | 301 |
|
213 | 302 |
if (diff > stirshaken_vs_cache_expire_s) { |
214 |
- LM_WARN("Cached certificate %s is behind expiration threshold (%zu > %zu). Need to download new certificate...\n", cert_full_path, diff, stirshaken_vs_cache_expire_s); |
|
303 |
+ LM_NOTICE("Cached certificate %s is behind expiration threshold (%lu > %zu). Need to download new certificate...\n", cert_full_path, diff, stirshaken_vs_cache_expire_s); |
|
215 | 304 |
goto exit; |
216 | 305 |
} else { |
217 |
- LM_WARN("Cached certificate %s is valid for next %zus\n", cert_full_path, stirshaken_vs_cache_expire_s - diff); |
|
306 |
+ LM_NOTICE("Cached certificate %s is valid for next %lus\n", cert_full_path, stirshaken_vs_cache_expire_s - diff); |
|
218 | 307 |
} |
219 | 308 |
} |
220 | 309 |
|
221 |
- if (!(cache_copy.x = stir_shaken_load_x509_from_file(&ss, cert_full_path))) { |
|
310 |
+ if (-1 == stirshaken_handle_cache_from_disk(&ss, &cache_copy, cert_full_path)) { |
|
222 | 311 |
LM_ERR("Cannot load X509 from file %s\n", cert_full_path); |
223 | 312 |
goto exit; |
224 | 313 |
} |
... | ... |
@@ -445,8 +534,8 @@ static int stirshaken_handle_cache(stir_shaken_context_t *ss, stir_shaken_passpo |
445 | 534 |
|
446 | 535 |
LM_DBG("Saving fresh certificate %s in cache (with name: %s)...\n", x5u, cert_full_path); |
447 | 536 |
|
448 |
- if (STIR_SHAKEN_STATUS_OK != stir_shaken_x509_to_disk(ss, cert->x, cert_full_path)) { |
|
449 |
- LM_ERR("Failed to write cert %s to disk (as: %s)", x5u, cert_full_path); |
|
537 |
+ if (-1 == stirshaken_handle_cache_to_disk(cert->x, cert->xchain, cert_full_path)) { |
|
538 |
+ LM_ERR("Failed to cache certificate %s to disk", x5u); |
|
450 | 539 |
} |
451 | 540 |
|
452 | 541 |
} else { |
... | ... |
@@ -485,7 +574,8 @@ static int ki_stirshaken_check_identity(sip_msg_t *msg) |
485 | 574 |
ibody = hf->body; |
486 | 575 |
|
487 | 576 |
if (STIR_SHAKEN_STATUS_OK != stir_shaken_vs_sih_verify(&ss, vs, ibody.s, &cert_out, &passport_out)) { |
488 |
- LM_ERR("SIP Identity Header did not pass verification\n"); |
|
577 |
+ LM_ERR("SIP Identity Header did not pass verification: %s", stir_shaken_get_error(&ss, NULL)); |
|
578 |
+ |
|
489 | 579 |
stirshaken_print_error_details(&ss); |
490 | 580 |
goto fail; |
491 | 581 |
} |