| 294 } |
294 } |
| 295 |
295 |
| 296 /* Forward declarations are fun! |
296 /* Forward declarations are fun! |
| 297 TODO: This is a stupid place for this */ |
297 TODO: This is a stupid place for this */ |
| 298 static Certificate * |
298 static Certificate * |
| 299 x509_import_from_datum(const gnutls_datum_t dt); |
299 x509_import_from_datum(const gnutls_datum_t dt, gnutls_x509_crt_fmt_t mode); |
| 300 |
300 |
| 301 static GList * |
301 static GList * |
| 302 ssl_gnutls_get_peer_certificates(PurpleSslConnection * gsc) |
302 ssl_gnutls_get_peer_certificates(PurpleSslConnection * gsc) |
| 303 { |
303 { |
| 304 PurpleSslGnutlsData *gnutls_data = PURPLE_SSL_GNUTLS_DATA(gsc); |
304 PurpleSslGnutlsData *gnutls_data = PURPLE_SSL_GNUTLS_DATA(gsc); |
| 320 cert_list = gnutls_certificate_get_peers(gnutls_data->session, |
320 cert_list = gnutls_certificate_get_peers(gnutls_data->session, |
| 321 &cert_list_size); |
321 &cert_list_size); |
| 322 |
322 |
| 323 /* Convert each certificate to a Certificate and append it to the list */ |
323 /* Convert each certificate to a Certificate and append it to the list */ |
| 324 for (i = 0; i < cert_list_size; i++) { |
324 for (i = 0; i < cert_list_size; i++) { |
| 325 Certificate * newcrt = x509_import_from_datum(cert_list[i]); |
325 Certificate * newcrt = x509_import_from_datum(cert_list[i], |
| |
326 GNUTLS_X509_FMT_DER); |
| 326 /* Append is somewhat inefficient on linked lists, but is easy |
327 /* Append is somewhat inefficient on linked lists, but is easy |
| 327 to read. If someone complains, I'll change it. |
328 to read. If someone complains, I'll change it. |
| 328 TODO: Is anyone complaining? (Maybe elb?) */ |
329 TODO: Is anyone complaining? (Maybe elb?) */ |
| 329 peer_certs = g_list_append(peer_certs, newcrt); |
330 peer_certs = g_list_append(peer_certs, newcrt); |
| 330 } |
331 } |
| 346 "x509" /* Scheme name */ |
347 "x509" /* Scheme name */ |
| 347 }; |
348 }; |
| 348 |
349 |
| 349 /** Transforms a gnutls_datum_t containing an X.509 certificate into a Certificate instance under the x509_gnutls scheme |
350 /** Transforms a gnutls_datum_t containing an X.509 certificate into a Certificate instance under the x509_gnutls scheme |
| 350 * |
351 * |
| 351 * @param dt Datum to transform |
352 * @param dt Datum to transform |
| |
353 * @param mode GnuTLS certificate format specifier (GNUTLS_X509_FMT_PEM for |
| |
354 * reading from files, and GNUTLS_X509_FMT_DER for converting |
| |
355 * "over the wire" certs for SSL) |
| 352 * |
356 * |
| 353 * @return A newly allocated Certificate structure of the x509_gnutls scheme |
357 * @return A newly allocated Certificate structure of the x509_gnutls scheme |
| 354 */ |
358 */ |
| 355 static Certificate * |
359 static Certificate * |
| 356 x509_import_from_datum(const gnutls_datum_t dt) |
360 x509_import_from_datum(const gnutls_datum_t dt, gnutls_x509_crt_fmt_t mode) |
| 357 { |
361 { |
| 358 /* Internal certificate data structure */ |
362 /* Internal certificate data structure */ |
| 359 gnutls_x509_crt_t *certdat; |
363 gnutls_x509_crt_t *certdat; |
| 360 /* New certificate to return */ |
364 /* New certificate to return */ |
| 361 Certificate * crt; |
365 Certificate * crt; |
| 364 certdat = g_new(gnutls_x509_crt_t, 1); |
368 certdat = g_new(gnutls_x509_crt_t, 1); |
| 365 gnutls_x509_crt_init(certdat); |
369 gnutls_x509_crt_init(certdat); |
| 366 |
370 |
| 367 /* Perform the actual certificate parse */ |
371 /* Perform the actual certificate parse */ |
| 368 /* Yes, certdat SHOULD be dereferenced */ |
372 /* Yes, certdat SHOULD be dereferenced */ |
| 369 gnutls_x509_crt_import(*certdat, &dt, GNUTLS_X509_FMT_PEM); |
373 gnutls_x509_crt_import(*certdat, &dt, mode); |
| 370 |
374 |
| 371 /* Allocate the certificate and load it with data */ |
375 /* Allocate the certificate and load it with data */ |
| 372 crt = g_new(Certificate, 1); |
376 crt = g_new(Certificate, 1); |
| 373 crt->scheme = &x509_gnutls; |
377 crt->scheme = &x509_gnutls; |
| 374 crt->data = certdat; |
378 crt->data = certdat; |