aboutsummaryrefslogtreecommitdiffstats
path: root/camel/camel-tcp-stream-ssl.c
diff options
context:
space:
mode:
Diffstat (limited to 'camel/camel-tcp-stream-ssl.c')
-rw-r--r--camel/camel-tcp-stream-ssl.c44
1 files changed, 41 insertions, 3 deletions
diff --git a/camel/camel-tcp-stream-ssl.c b/camel/camel-tcp-stream-ssl.c
index 31a69eb371..15b3dcd8fb 100644
--- a/camel/camel-tcp-stream-ssl.c
+++ b/camel/camel-tcp-stream-ssl.c
@@ -27,6 +27,7 @@
* will be used instead.
*/
+
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
@@ -55,7 +56,7 @@
#include "camel-tcp-stream-ssl.h"
#include "camel-session.h"
-
+#include "camel-certdb.h"
/* from md5-utils.h */
void md5_get_digest (const char *buffer, int buffer_size, unsigned char digest[16]);
@@ -468,6 +469,8 @@ ssl_bad_cert (void *data, PRFileDesc *sockfd)
{
unsigned char md5sum[16], fingerprint[40], *f;
gboolean accept, valid_cert;
+ CamelCertDB *certdb = NULL;
+ CamelCert *ccert = NULL;
char *prompt, *cert_str;
CamelTcpStreamSSL *ssl;
CERTCertificate *cert;
@@ -492,6 +495,32 @@ ssl_bad_cert (void *data, PRFileDesc *sockfd)
/*issuer = CERT_FindCertByName (CERT_GetDefaultCertDB (), &cert->derIssuer);
valid_cert = issuer && CERT_VerifySignedData (&cert->signatureWrap, issuer, PR_Now (), NULL);*/
+ /* first check our own certificate database to see if we accepted the cert (nss's certdb seems to not work) */
+ certdb = camel_certdb_get_default ();
+ if (certdb) {
+ ccert = camel_certdb_get_cert (certdb, fingerprint);
+ if (ccert) {
+ if (ccert->trust != CAMEL_CERT_TRUST_UNKNOWN) {
+ accept = ccert->trust != CAMEL_CERT_TRUST_NEVER;
+ camel_certdb_cert_unref (certdb, ccert);
+ camel_object_unref (certdb);
+
+ return accept ? SECSuccess : SECFailure;
+ }
+ } else {
+ /* create a new camel-cert */
+ ccert = camel_certdb_cert_new (certdb);
+ camel_cert_set_issuer (certdb, ccert, CERT_NameToAscii (&cert->issuer));
+ camel_cert_set_subject (certdb, ccert, CERT_NameToAscii (&cert->subject));
+ camel_cert_set_hostname (certdb, ccert, ssl->priv->expected_host);
+ camel_cert_set_fingerprint (certdb, ccert, fingerprint);
+ camel_cert_set_trust (certdb, ccert, CAMEL_CERT_TRUST_UNKNOWN);
+
+ /* Add the certificate to our db */
+ camel_certdb_add (certdb, ccert);
+ }
+ }
+
cert_str = g_strdup_printf (_("Issuer: %s\n"
"Subject: %s\n"
"Fingerprint: %s\n"
@@ -533,10 +562,19 @@ ssl_bad_cert (void *data, PRFileDesc *sockfd)
CERT_ImportCerts (CERT_GetDefaultCertDB (), certUsageSSLServer, 1, certs,
NULL, TRUE, FALSE, cert->nickname);
#endif
- return SECSuccess;
+
+ if (ccert) {
+ camel_cert_set_trust (certdb, ccert, CAMEL_CERT_TRUST_FULLY);
+ camel_certdb_touch (certdb);
+ }
+ }
+
+ if (certdb) {
+ camel_certdb_cert_unref (certdb, ccert);
+ camel_object_unref (certdb);
}
- return SECFailure;
+ return accept ? SECSuccess : SECFailure;
}
static PRFileDesc *