Mercurial > pidgin
comparison libpurple/certificate.c @ 27664:151ec92db74c
Check expiration/activation times on certificates. Closes #8226.
author | Paul Aurich <paul@darkrain42.org> |
---|---|
date | Wed, 22 Jul 2009 04:14:01 +0000 |
parents | 199cf148cdf8 |
children | 4c5f35f2b1ff 6dd97a284d65 |
comparison
equal
deleted
inserted
replaced
27663:e8e056876e39 | 27664:151ec92db74c |
---|---|
193 purple_certificate_check_signature_chain(GList *chain) | 193 purple_certificate_check_signature_chain(GList *chain) |
194 { | 194 { |
195 GList *cur; | 195 GList *cur; |
196 PurpleCertificate *crt, *issuer; | 196 PurpleCertificate *crt, *issuer; |
197 gchar *uid; | 197 gchar *uid; |
198 time_t now, activation, expiration; | |
199 gboolean ret; | |
198 | 200 |
199 g_return_val_if_fail(chain, FALSE); | 201 g_return_val_if_fail(chain, FALSE); |
200 | 202 |
201 uid = purple_certificate_get_unique_id((PurpleCertificate *) chain->data); | 203 uid = purple_certificate_get_unique_id((PurpleCertificate *) chain->data); |
202 purple_debug_info("certificate", | 204 purple_debug_info("certificate", |
209 purple_debug_info("certificate", | 211 purple_debug_info("certificate", |
210 "...Singleton. We'll say it's valid.\n"); | 212 "...Singleton. We'll say it's valid.\n"); |
211 return TRUE; | 213 return TRUE; |
212 } | 214 } |
213 | 215 |
216 now = time(NULL); | |
217 | |
214 /* Load crt with the first certificate */ | 218 /* Load crt with the first certificate */ |
215 crt = (PurpleCertificate *)(chain->data); | 219 crt = (PurpleCertificate *)(chain->data); |
216 /* And start with the second certificate in the chain */ | 220 /* And start with the second certificate in the chain */ |
217 for ( cur = chain->next; cur; cur = cur->next ) { | 221 for ( cur = chain->next; cur; cur = cur->next ) { |
218 | 222 |
219 issuer = (PurpleCertificate *)(cur->data); | 223 issuer = (PurpleCertificate *)(cur->data); |
220 | 224 |
225 uid = purple_certificate_get_unique_id(issuer); | |
226 | |
227 ret = purple_certificate_get_times(issuer, &activation, &expiration); | |
228 if (!ret || now < activation || now > expiration) { | |
229 if (!ret) | |
230 purple_debug_error("certificate", | |
231 "...Failed to get validity times for certificate %s\n" | |
232 "Chain is INVALID\n", uid); | |
233 else if (now > expiration) | |
234 purple_debug_error("certificate", | |
235 "...Issuer %s expired at %s\nChain is INVALID\n", | |
236 uid, ctime(&expiration)); | |
237 else | |
238 purple_debug_error("certificate", | |
239 "...Not-yet-activated issuer %s will be valid at %s\n" | |
240 "Chain is INVALID\n", uid, ctime(&activation)); | |
241 | |
242 g_free(uid); | |
243 return FALSE; | |
244 } | |
245 | |
221 /* Check the signature for this link */ | 246 /* Check the signature for this link */ |
222 if (! purple_certificate_signed_by(crt, issuer) ) { | 247 if (! purple_certificate_signed_by(crt, issuer) ) { |
223 uid = purple_certificate_get_unique_id(issuer); | |
224 purple_debug_error("certificate", | 248 purple_debug_error("certificate", |
225 "...Bad or missing signature by %s\nChain is INVALID\n", | 249 "...Bad or missing signature by %s\nChain is INVALID\n", |
226 uid); | 250 uid); |
227 g_free(uid); | 251 g_free(uid); |
228 | 252 |
229 return FALSE; | 253 return FALSE; |
230 } | 254 } |
231 | 255 |
232 uid = purple_certificate_get_unique_id(issuer); | |
233 purple_debug_info("certificate", | 256 purple_debug_info("certificate", |
234 "...Good signature by %s\n", | 257 "...Good signature by %s\n", |
235 uid); | 258 uid); |
236 g_free(uid); | 259 g_free(uid); |
237 | 260 |
359 g_return_val_if_fail( (activation != NULL) || (expiration != NULL), FALSE); | 382 g_return_val_if_fail( (activation != NULL) || (expiration != NULL), FALSE); |
360 | 383 |
361 /* Throw the request on down to the certscheme */ | 384 /* Throw the request on down to the certscheme */ |
362 return (scheme->get_times)(crt, activation, expiration); | 385 return (scheme->get_times)(crt, activation, expiration); |
363 } | 386 } |
364 | |
365 | 387 |
366 gchar * | 388 gchar * |
367 purple_certificate_pool_mkpath(PurpleCertificatePool *pool, const gchar *id) | 389 purple_certificate_pool_mkpath(PurpleCertificatePool *pool, const gchar *id) |
368 { | 390 { |
369 gchar *path; | 391 gchar *path; |
1459 static void | 1481 static void |
1460 x509_tls_cached_start_verify(PurpleCertificateVerificationRequest *vrq) | 1482 x509_tls_cached_start_verify(PurpleCertificateVerificationRequest *vrq) |
1461 { | 1483 { |
1462 const gchar *tls_peers_name = "tls_peers"; /* Name of local cache */ | 1484 const gchar *tls_peers_name = "tls_peers"; /* Name of local cache */ |
1463 PurpleCertificatePool *tls_peers; | 1485 PurpleCertificatePool *tls_peers; |
1486 time_t now, activation, expiration; | |
1487 gboolean ret; | |
1464 | 1488 |
1465 g_return_if_fail(vrq); | 1489 g_return_if_fail(vrq); |
1466 | 1490 |
1467 purple_debug_info("certificate/x509/tls_cached", | 1491 purple_debug_info("certificate/x509/tls_cached", |
1468 "Starting verify for %s\n", | 1492 "Starting verify for %s\n", |
1469 vrq->subject_name); | 1493 vrq->subject_name); |
1494 | |
1495 /* | |
1496 * Verify the first certificate (the main one) has been activated and | |
1497 * isn't expired, i.e. activation < now < expiration. | |
1498 */ | |
1499 now = time(NULL); | |
1500 ret = purple_certificate_get_times(vrq->cert_chain->data, &activation, | |
1501 &expiration); | |
1502 if (!ret || now > expiration || now < activation) { | |
1503 gchar *secondary; | |
1504 | |
1505 if (!ret) | |
1506 purple_debug_error("certificate/x509/tls_cached", | |
1507 "Failed to get validity times for certificate %s\n", | |
1508 vrq->subject_name); | |
1509 else if (now > expiration) | |
1510 purple_debug_error("certificate/x509/tls_cached", | |
1511 "Certificate %s expired at %s\n", | |
1512 vrq->subject_name, ctime(&expiration)); | |
1513 else | |
1514 purple_debug_error("certificate/x509/tls_cached", | |
1515 "Certificate %s is not yet valid, will be at %s\n", | |
1516 vrq->subject_name, ctime(&activation)); | |
1517 | |
1518 /* FIXME 2.6.1 */ | |
1519 secondary = g_strdup_printf(_("The certificate chain presented" | |
1520 " for %s is not valid."), | |
1521 vrq->subject_name); | |
1522 | |
1523 purple_notify_error(NULL, /* TODO: Probably wrong. */ | |
1524 _("SSL Certificate Error"), | |
1525 _("Invalid certificate chain"), | |
1526 secondary ); | |
1527 g_free(secondary); | |
1528 | |
1529 /* Okay, we're done here */ | |
1530 purple_certificate_verify_complete(vrq, | |
1531 PURPLE_CERTIFICATE_INVALID); | |
1532 return; | |
1533 } | |
1470 | 1534 |
1471 tls_peers = purple_certificate_find_pool(x509_tls_cached.scheme_name,tls_peers_name); | 1535 tls_peers = purple_certificate_find_pool(x509_tls_cached.scheme_name,tls_peers_name); |
1472 | 1536 |
1473 if (!tls_peers) { | 1537 if (!tls_peers) { |
1474 purple_debug_error("certificate/x509/tls_cached", | 1538 purple_debug_error("certificate/x509/tls_cached", |