comparison libpurple/plugins/ssl/ssl-gnutls.c @ 17914:2f119e2a1b33

- Wrote GnuTLS get_peer_certificates function
author William Ehlhardt <williamehlhardt@gmail.com>
date Sat, 02 Jun 2007 06:33:48 +0000
parents 55a0b0a42000
children 80c909c5bb7a
comparison
equal deleted inserted replaced
17913:55a0b0a42000 17914:2f119e2a1b33
291 } 291 }
292 292
293 return s; 293 return s;
294 } 294 }
295 295
296 /* Forward declarations are fun!
297 TODO: This is a stupid place for this */
298 static Certificate *
299 x509_import_from_datum(const gnutls_datum_t dt);
300
301 static GList *
302 ssl_gnutls_get_peer_certificates(PurpleSslConnection * gsc)
303 {
304 PurpleSslGnutlsData *gnutls_data = PURPLE_SSL_GNUTLS_DATA(gsc);
305
306 /* List of Certificate instances to return */
307 GList * peer_certs = NULL;
308
309 /* List of raw certificates as given by GnuTLS */
310 const gnutls_datum_t *cert_list;
311 unsigned int cert_list_size = 0;
312
313 unsigned int i;
314
315 /* This should never, ever happen. */
316 g_return_val_if_fail( gnutls_certificate_type_get (gnutls_data->session) == GNUTLS_CRT_X509, NULL);
317
318 /* Get the certificate list from GnuTLS */
319 /* TODO: I am _pretty sure_ this doesn't block or do other exciting things */
320 cert_list = gnutls_certificate_get_peers(gnutls_data->session,
321 &cert_list_size);
322
323 /* Convert each certificate to a Certificate and append it to the list */
324 for (i = 0; i < cert_list_size; i++) {
325 Certificate * newcrt = x509_import_from_datum(cert_list[i]);
326 /* Append is somewhat inefficient on linked lists, but is easy
327 to read. If someone complains, I'll change it.
328 TODO: Is anyone complaining? (Maybe elb?) */
329 peer_certs = g_list_append(peer_certs, newcrt);
330 }
331
332 /* cert_list shouldn't need free()-ing */
333 /* TODO: double-check this */
334
335 return peer_certs;
336 }
337
296 /************************************************************************/ 338 /************************************************************************/
297 /* X.509 functionality */ 339 /* X.509 functionality */
298 /************************************************************************/ 340 /************************************************************************/
299 const gchar * SCHEME_NAME = "x509"; 341 const gchar * SCHEME_NAME = "x509";
300 342
302 /* TODO: Flesh this out! */ 344 /* TODO: Flesh this out! */
303 static CertificateScheme x509_gnutls = { 345 static CertificateScheme x509_gnutls = {
304 "x509" /* Scheme name */ 346 "x509" /* Scheme name */
305 }; 347 };
306 348
349 /** Transforms a gnutls_datum_t containing an X.509 certificate into a Certificate instance under the x509_gnutls scheme
350 *
351 * @param dt Datum to transform
352 *
353 * @return A newly allocated Certificate structure of the x509_gnutls scheme
354 */
355 static Certificate *
356 x509_import_from_datum(const gnutls_datum_t dt)
357 {
358 /* Internal certificate data structure */
359 gnutls_x509_crt_t *certdat;
360 /* New certificate to return */
361 Certificate * crt;
362
363 /* Allocate and prepare the internal certificate data */
364 certdat = g_new(gnutls_x509_crt_t, 1);
365 gnutls_x509_crt_init(certdat);
366
367 /* Perform the actual certificate parse */
368 /* Yes, certdat SHOULD be dereferenced */
369 gnutls_x509_crt_import(*certdat, &dt, GNUTLS_X509_FMT_PEM);
370
371 /* Allocate the certificate and load it with data */
372 crt = g_new(Certificate, 1);
373 crt->scheme = &x509_gnutls;
374 crt->data = certdat;
375
376 return crt;
377 }
378
307 /** Imports a PEM-formatted X.509 certificate from the specified file. 379 /** Imports a PEM-formatted X.509 certificate from the specified file.
308 * @param filename Filename to import from. Format is PEM 380 * @param filename Filename to import from. Format is PEM
309 * 381 *
310 * @return A newly allocated Certificate structure of the x509_gnutls scheme 382 * @return A newly allocated Certificate structure of the x509_gnutls scheme
311 */ 383 */
313 x509_import_from_file(const gchar * filename) 385 x509_import_from_file(const gchar * filename)
314 { 386 {
315 Certificate *crt; /* Certificate being constructed */ 387 Certificate *crt; /* Certificate being constructed */
316 gchar *buf; /* Used to load the raw file data */ 388 gchar *buf; /* Used to load the raw file data */
317 gsize buf_sz; /* Size of the above */ 389 gsize buf_sz; /* Size of the above */
318 gnutls_datum_t dt; /* Struct to pass to GnuTLS */ 390 gnutls_datum_t dt; /* Struct to pass down to GnuTLS */
319
320 /* Internal certificate data structure */
321 gnutls_x509_crt_t *certdat;
322 391
323 purple_debug_info("gnutls", 392 purple_debug_info("gnutls",
324 "Attempting to load X.509 certificate from %s\n", 393 "Attempting to load X.509 certificate from %s\n",
325 filename); 394 filename);
326 395
332 &buf, 401 &buf,
333 &buf_sz, 402 &buf_sz,
334 NULL /* No error checking for now */ 403 NULL /* No error checking for now */
335 ); 404 );
336 405
337 /* Allocate and prepare the internal certificate data */
338 certdat = g_new(gnutls_x509_crt_t, 1);
339 gnutls_x509_crt_init(certdat);
340
341 /* Load the datum struct */ 406 /* Load the datum struct */
342 dt.data = (unsigned char *) buf; 407 dt.data = (unsigned char *) buf;
343 dt.size = buf_sz; 408 dt.size = buf_sz;
344 409
345 /* Perform the actual certificate parse */ 410 /* Perform the conversion */
346 /* Yes, certdat SHOULD be dereferenced */ 411 crt = x509_import_from_datum(dt);
347 gnutls_x509_crt_import(*certdat, &dt, GNUTLS_X509_FMT_PEM);
348 412
349 /* Allocate the certificate and load it with data */
350 crt = g_new(Certificate, 1);
351 crt->scheme = &x509_gnutls;
352 crt->data = certdat;
353
354 /* Cleanup */ 413 /* Cleanup */
355 g_free(buf); 414 g_free(buf);
356 415
357 return crt; 416 return crt;
358 } 417 }