comparison libpurple/certificate.h @ 19265:ce892eddb8f1

propagate from branch 'im.pidgin.pidgin' (head 37a828a3519f5c2fe7a6d94dc41d607b807dd371) to branch 'im.pidgin.soc.2007.certmgr' (head 462298218a3d857c74beff14713b6b92743e3b08)
author William Ehlhardt <williamehlhardt@gmail.com>
date Tue, 14 Aug 2007 04:52:22 +0000
parents b98151ac2251
children e93db0c87b26
comparison
equal deleted inserted replaced
19264:d5e76ad4b365 19265:ce892eddb8f1
1 /**
2 * @file certificate.h Public-Key Certificate API
3 * @ingroup core
4 */
5
6 /*
7 *
8 * purple
9 *
10 * Purple is the legal property of its developers, whose names are too numerous
11 * to list here. Please refer to the COPYRIGHT file distributed with this
12 * source distribution.
13 *
14 * This program is free software; you can redistribute it and/or modify
15 * it under the terms of the GNU General Public License as published by
16 * the Free Software Foundation; either version 2 of the License, or
17 * (at your option) any later version.
18 *
19 * This program is distributed in the hope that it will be useful,
20 * but WITHOUT ANY WARRANTY; without even the implied warranty of
21 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22 * GNU General Public License for more details.
23 *
24 * You should have received a copy of the GNU General Public License
25 * along with this program; if not, write to the Free Software
26 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
27 */
28
29 #ifndef _PURPLE_CERTIFICATE_H
30 #define _PURPLE_CERTIFICATE_H
31
32 #include <glib.h>
33
34 #ifdef __cplusplus
35 extern "C" {
36 #endif /* __cplusplus */
37
38
39 typedef enum
40 {
41 PURPLE_CERTIFICATE_INVALID = 0,
42 PURPLE_CERTIFICATE_VALID = 1
43 } PurpleCertificateVerificationStatus;
44
45 typedef struct _PurpleCertificate PurpleCertificate;
46 typedef struct _PurpleCertificatePool PurpleCertificatePool;
47 typedef struct _PurpleCertificateScheme PurpleCertificateScheme;
48 typedef struct _PurpleCertificateVerifier PurpleCertificateVerifier;
49 typedef struct _PurpleCertificateVerificationRequest PurpleCertificateVerificationRequest;
50
51 /**
52 * Callback function for the results of a verification check
53 * @param st Status code
54 * @param userdata User-defined data
55 */
56 typedef void (*PurpleCertificateVerifiedCallback)
57 (PurpleCertificateVerificationStatus st,
58 gpointer userdata);
59
60 /** A certificate instance
61 *
62 * An opaque data structure representing a single certificate under some
63 * CertificateScheme
64 */
65 struct _PurpleCertificate
66 {
67 /** Scheme this certificate is under */
68 PurpleCertificateScheme * scheme;
69 /** Opaque pointer to internal data */
70 gpointer data;
71 };
72
73 /**
74 * Database for retrieval or storage of Certificates
75 *
76 * More or less a hash table; all lookups and writes are controlled by a string
77 * key.
78 */
79 struct _PurpleCertificatePool
80 {
81 /** Scheme this Pool operates for */
82 gchar *scheme_name;
83 /** Internal name to refer to the pool by */
84 gchar *name;
85
86 /** User-friendly name for this type
87 * ex: N_("SSL Servers")
88 * When this is displayed anywhere, it should be i18ned
89 * ex: _(pool->fullname)
90 */
91 gchar *fullname;
92
93 /** Internal pool data */
94 gpointer data;
95
96 /**
97 * Set up the Pool's internal state
98 *
99 * Upon calling purple_certificate_register_pool() , this function will
100 * be called. May be NULL.
101 * @return TRUE if the initialization succeeded, otherwise FALSE
102 */
103 gboolean (* init)(void);
104
105 /**
106 * Uninit the Pool's internal state
107 *
108 * Will be called by purple_certificate_unregister_pool() . May be NULL
109 */
110 void (* uninit)(void);
111
112 /** Check for presence of a certificate in the pool using unique ID */
113 gboolean (* cert_in_pool)(const gchar *id);
114 /** Retrieve a PurpleCertificate from the pool */
115 PurpleCertificate * (* get_cert)(const gchar *id);
116 /** Add a certificate to the pool. Must overwrite any other
117 * certificates sharing the same ID in the pool.
118 * @return TRUE if the operation succeeded, otherwise FALSE
119 */
120 gboolean (* put_cert)(const gchar *id, PurpleCertificate *crt);
121 /** Delete a certificate from the pool */
122 gboolean (* delete_cert)(const gchar *id);
123
124 /** Returns a list of IDs stored in the pool */
125 GList * (* get_idlist)(void);
126 };
127
128 /** A certificate type
129 *
130 * A CertificateScheme must implement all of the fields in the structure,
131 * and register it using purple_certificate_register_scheme()
132 *
133 * There may be only ONE CertificateScheme provided for each certificate
134 * type, as specified by the "name" field.
135 */
136 struct _PurpleCertificateScheme
137 {
138 /** Name of the certificate type
139 * ex: "x509", "pgp", etc.
140 * This must be globally unique - you may not register more than one
141 * CertificateScheme of the same name at a time.
142 */
143 gchar * name;
144
145 /** User-friendly name for this type
146 * ex: N_("X.509 Certificates")
147 * When this is displayed anywhere, it should be i18ned
148 * ex: _(scheme->fullname)
149 */
150 gchar * fullname;
151
152 /** Imports a certificate from a file
153 *
154 * @param filename File to import the certificate from
155 * @return Pointer to the newly allocated Certificate struct
156 * or NULL on failure.
157 */
158 PurpleCertificate * (* import_certificate)(const gchar * filename);
159
160 /**
161 * Exports a certificate to a file
162 *
163 * @param filename File to export the certificate to
164 * @param crt Certificate to export
165 * @return TRUE if the export succeeded, otherwise FALSE
166 * @see purple_certificate_export()
167 */
168 gboolean (* export_certificate)(const gchar *filename, PurpleCertificate *crt);
169
170 /**
171 * Duplicates a certificate
172 *
173 * Certificates are generally assumed to be read-only, so feel free to
174 * do any sort of reference-counting magic you want here. If this ever
175 * changes, please remember to change the magic accordingly.
176 * @return Reference to the new copy
177 */
178 PurpleCertificate * (* copy_certificate)(PurpleCertificate *crt);
179
180 /** Destroys and frees a Certificate structure
181 *
182 * Destroys a Certificate's internal data structures and calls
183 * free(crt)
184 *
185 * @param crt Certificate instance to be destroyed. It WILL NOT be
186 * destroyed if it is not of the correct
187 * CertificateScheme. Can be NULL
188 */
189 void (* destroy_certificate)(PurpleCertificate * crt);
190
191 /** Find whether "crt" has a valid signature from issuer "issuer"
192 * @see purple_certificate_signed_by() */
193 gboolean (*signed_by)(PurpleCertificate *crt, PurpleCertificate *issuer);
194 /**
195 * Retrieves the certificate public key fingerprint using SHA1
196 *
197 * @param crt Certificate instance
198 * @return Binary representation of SHA1 hash - must be freed using
199 * g_byte_array_free()
200 */
201 GByteArray * (* get_fingerprint_sha1)(PurpleCertificate *crt);
202
203 /**
204 * Retrieves a unique certificate identifier
205 *
206 * @param crt Certificate instance
207 * @return Newly allocated string that can be used to uniquely
208 * identify the certificate.
209 */
210 gchar * (* get_unique_id)(PurpleCertificate *crt);
211
212 /**
213 * Retrieves a unique identifier for the certificate's issuer
214 *
215 * @param crt Certificate instance
216 * @return Newly allocated string that can be used to uniquely
217 * identify the issuer's certificate.
218 */
219 gchar * (* get_issuer_unique_id)(PurpleCertificate *crt);
220
221 /**
222 * Gets the certificate subject's name
223 *
224 * For X.509, this is the "Common Name" field, as we're only using it
225 * for hostname verification at the moment
226 *
227 * @see purple_certificate_get_subject_name()
228 *
229 * @param crt Certificate instance
230 * @return Newly allocated string with the certificate subject.
231 */
232 gchar * (* get_subject_name)(PurpleCertificate *crt);
233
234 /**
235 * Check the subject name against that on the certificate
236 * @see purple_certificate_check_subject_name()
237 * @return TRUE if it is a match, else FALSE
238 */
239 gboolean (* check_subject_name)(PurpleCertificate *crt, const gchar *name);
240
241 /** Retrieve the certificate activation/expiration times */
242 gboolean (* get_times)(PurpleCertificate *crt, time_t *activation, time_t *expiration);
243
244 /* TODO: Fill out this structure */
245 };
246
247 /** A set of operations used to provide logic for verifying a Certificate's
248 * authenticity.
249 *
250 * A Verifier provider must fill out these fields, then register it using
251 * purple_certificate_register_verifier()
252 *
253 * The (scheme_name, name) value must be unique for each Verifier - you may not
254 * register more than one Verifier of the same name for each Scheme
255 */
256 struct _PurpleCertificateVerifier
257 {
258 /** Name of the scheme this Verifier operates on
259 *
260 * The scheme will be looked up by name when a Request is generated
261 * using this Verifier
262 */
263 gchar *scheme_name;
264
265 /** Name of the Verifier - case insensitive */
266 gchar *name;
267
268 /**
269 * Start the verification process
270 *
271 * To be called from purple_certificate_verify once it has
272 * constructed the request. This will use the information in the
273 * given VerificationRequest to check the certificate and callback
274 * the requester with the verification results.
275 *
276 * @param vrq Request to process
277 */
278 void (* start_verification)(PurpleCertificateVerificationRequest *vrq);
279
280 /**
281 * Destroy a completed Request under this Verifier
282 * The function pointed to here is only responsible for cleaning up
283 * whatever PurpleCertificateVerificationRequest::data points to.
284 * It should not call free(vrq)
285 *
286 * @param vrq Request to destroy
287 */
288 void (* destroy_request)(PurpleCertificateVerificationRequest *vrq);
289 };
290
291 /** Structure for a single certificate request
292 *
293 * Useful for keeping track of the state of a verification that involves
294 * several steps
295 */
296 struct _PurpleCertificateVerificationRequest
297 {
298 /** Reference to the verification logic used */
299 PurpleCertificateVerifier *verifier;
300 /** Reference to the scheme used.
301 *
302 * This is looked up from the Verifier when the Request is generated
303 */
304 PurpleCertificateScheme *scheme;
305
306 /**
307 * Name to check that the certificate is issued to
308 *
309 * For X.509 certificates, this is the Common Name
310 */
311 gchar *subject_name;
312
313 /** List of certificates in the chain to be verified (such as that returned by purple_ssl_get_peer_certificates )
314 *
315 * This is most relevant for X.509 certificates used in SSL sessions.
316 * The list order should be: certificate, issuer, issuer's issuer, etc.
317 */
318 GList *cert_chain;
319
320 /** Internal data used by the Verifier code */
321 gpointer data;
322
323 /** Function to call with the verification result */
324 PurpleCertificateVerifiedCallback cb;
325 /** Data to pass to the post-verification callback */
326 gpointer cb_data;
327 };
328
329 /*****************************************************************************/
330 /** @name Certificate Verification Functions */
331 /*****************************************************************************/
332 /*@{*/
333
334 /**
335 * Constructs a verification request and passed control to the specified Verifier
336 *
337 * It is possible that the callback will be called immediately upon calling
338 * this function. Plan accordingly.
339 *
340 * @param verifier Verification logic to use.
341 * @see purple_certificate_find_verifier()
342 *
343 * @param subject_name Name that should match the first certificate in the
344 * chain for the certificate to be valid. Will be strdup'd
345 * into the Request struct
346 *
347 * @param cert_chain Certificate chain to check. If there is more than one
348 * certificate in the chain (X.509), the peer's
349 * certificate comes first, then the issuer/signer's
350 * certificate, etc. The whole list is duplicated into the
351 * Request struct.
352 *
353 * @param cb Callback function to be called with whether the
354 * certificate was approved or not.
355 * @param cb_data User-defined data for the above.
356 */
357 void
358 purple_certificate_verify (PurpleCertificateVerifier *verifier,
359 const gchar *subject_name, GList *cert_chain,
360 PurpleCertificateVerifiedCallback cb,
361 gpointer cb_data);
362
363 /**
364 * Completes and destroys a VerificationRequest
365 *
366 * @param vrq Request to conclude
367 * @param st Success/failure code to pass to the request's
368 * completion callback.
369 */
370 void
371 purple_certificate_verify_complete(PurpleCertificateVerificationRequest *vrq,
372 PurpleCertificateVerificationStatus st);
373
374 /*@}*/
375
376 /*****************************************************************************/
377 /** @name Certificate Functions */
378 /*****************************************************************************/
379 /*@{*/
380
381 /**
382 * Makes a duplicate of a certificate
383 *
384 * @param crt Instance to duplicate
385 * @return Pointer to new instance
386 */
387 PurpleCertificate *
388 purple_certificate_copy(PurpleCertificate *crt);
389
390 /**
391 * Duplicates an entire list of certificates
392 *
393 * @param crt_list List to duplicate
394 * @return New list copy
395 */
396 GList *
397 purple_certificate_copy_list(GList *crt_list);
398
399 /**
400 * Destroys and free()'s a Certificate
401 *
402 * @param crt Instance to destroy. May be NULL.
403 */
404 void
405 purple_certificate_destroy (PurpleCertificate *crt);
406
407 /**
408 * Destroy an entire list of Certificate instances and the containing list
409 *
410 * @param crt_list List of certificates to destroy. May be NULL.
411 */
412 void
413 purple_certificate_destroy_list (GList * crt_list);
414
415 /**
416 * Check whether 'crt' has a valid signature made by 'issuer'
417 *
418 * @param crt Certificate instance to check signature of
419 * @param issuer Certificate thought to have signed 'crt'
420 *
421 * @return TRUE if 'crt' has a valid signature made by 'issuer',
422 * otherwise FALSE
423 * @TODO Find a way to give the reason (bad signature, not the issuer, etc.)
424 */
425 gboolean
426 purple_certificate_signed_by(PurpleCertificate *crt, PurpleCertificate *issuer);
427
428 /**
429 * Check that a certificate chain is valid
430 *
431 * Uses purple_certificate_signed_by() to verify that each PurpleCertificate
432 * in the chain carries a valid signature from the next. A single-certificate
433 * chain is considered to be valid.
434 *
435 * @param chain List of PurpleCertificate instances comprising the chain,
436 * in the order certificate, issuer, issuer's issuer, etc.
437 * @return TRUE if the chain is valid. See description.
438 * @TODO Specify which certificate in the chain caused a failure
439 */
440 gboolean
441 purple_certificate_check_signature_chain(GList *chain);
442
443 /**
444 * Imports a PurpleCertificate from a file
445 *
446 * @param scheme Scheme to import under
447 * @param filename File path to import from
448 * @return Pointer to a new PurpleCertificate, or NULL on failure
449 */
450 PurpleCertificate *
451 purple_certificate_import(PurpleCertificateScheme *scheme, const gchar *filename);
452
453 /**
454 * Exports a PurpleCertificate to a file
455 *
456 * @param filename File to export the certificate to
457 * @param crt Certificate to export
458 * @return TRUE if the export succeeded, otherwise FALSE
459 */
460 gboolean
461 purple_certificate_export(const gchar *filename, PurpleCertificate *crt);
462
463
464 /**
465 * Retrieves the certificate public key fingerprint using SHA1.
466 *
467 * @param crt Certificate instance
468 * @return Binary representation of the hash. You are responsible for free()ing
469 * this.
470 * @see purple_base16_encode_chunked()
471 */
472 GByteArray *
473 purple_certificate_get_fingerprint_sha1(PurpleCertificate *crt);
474
475 /**
476 * Get a unique identifier for the certificate
477 *
478 * @param crt Certificate instance
479 * @return String representing the certificate uniquely. Must be g_free()'ed
480 */
481 gchar *
482 purple_certificate_get_unique_id(PurpleCertificate *crt);
483
484 /**
485 * Get a unique identifier for the certificate's issuer
486 *
487 * @param crt Certificate instance
488 * @return String representing the certificate's issuer uniquely. Must be
489 * g_free()'ed
490 */
491 gchar *
492 purple_certificate_get_issuer_unique_id(PurpleCertificate *crt);
493
494 /**
495 * Gets the certificate subject's name
496 *
497 * For X.509, this is the "Common Name" field, as we're only using it
498 * for hostname verification at the moment
499 *
500 * @param crt Certificate instance
501 * @return Newly allocated string with the certificate subject.
502 */
503 gchar *
504 purple_certificate_get_subject_name(PurpleCertificate *crt);
505
506 /**
507 * Check the subject name against that on the certificate
508 * @param crt Certificate instance
509 * @param name Name to check.
510 * @return TRUE if it is a match, else FALSE
511 */
512 gboolean
513 purple_certificate_check_subject_name(PurpleCertificate *crt, const gchar *name);
514
515 /**
516 * Get the expiration/activation times.
517 *
518 * @param crt Certificate instance
519 * @param activation Reference to store the activation time at. May be NULL
520 * if you don't actually want it.
521 * @param expiration Reference to store the expiration time at. May be NULL
522 * if you don't actually want it.
523 * @return TRUE if the requested values were obtained, otherwise FALSE.
524 */
525 gboolean
526 purple_certificate_get_times(PurpleCertificate *crt, time_t *activation, time_t *expiration);
527
528 /*@}*/
529
530 /*****************************************************************************/
531 /** @name Certificate Pool Functions */
532 /*****************************************************************************/
533 /*@{*/
534 /**
535 * Helper function for generating file paths in ~/.purple/certificates for
536 * CertificatePools that use them.
537 *
538 * All components will be escaped for filesystem friendliness.
539 *
540 * @param pool CertificatePool to build a path for
541 * @param id Key to look up a Certificate by. May be NULL.
542 * @return A newly allocated path of the form
543 * ~/.purple/certificates/scheme_name/pool_name/unique_id
544 */
545 gchar *
546 purple_certificate_pool_mkpath(PurpleCertificatePool *pool, const gchar *id);
547
548 /**
549 * Determines whether a pool can be used.
550 *
551 * Checks whether the associated CertificateScheme is loaded.
552 *
553 * @param pool Pool to check
554 *
555 * @return TRUE if the pool can be used, otherwise FALSE
556 */
557 gboolean
558 purple_certificate_pool_usable(PurpleCertificatePool *pool);
559
560 /**
561 * Looks up the scheme the pool operates under
562 *
563 * @param pool Pool to get the scheme of
564 *
565 * @return Pointer to the pool's scheme, or NULL if it isn't loaded.
566 * @see purple_certificate_pool_usable()
567 */
568 PurpleCertificateScheme *
569 purple_certificate_pool_get_scheme(PurpleCertificatePool *pool);
570
571 /**
572 * Check for presence of an ID in a pool.
573 * @param pool Pool to look in
574 * @param id ID to look for
575 * @return TRUE if the ID is in the pool, else FALSE
576 */
577 gboolean
578 purple_certificate_pool_contains(PurpleCertificatePool *pool, const gchar *id);
579
580 /**
581 * Retrieve a certificate from a pool.
582 * @param pool Pool to fish in
583 * @param id ID to look up
584 * @return Retrieved certificate, or NULL if it wasn't there
585 */
586 PurpleCertificate *
587 purple_certificate_pool_retrieve(PurpleCertificatePool *pool, const gchar *id);
588
589 /**
590 * Add a certificate to a pool
591 *
592 * Any pre-existing certificate of the same ID will be overwritten.
593 *
594 * @param pool Pool to add to
595 * @param id ID to store the certificate with
596 * @param crt Certificate to store
597 * @return TRUE if the operation succeeded, otherwise FALSE
598 */
599 gboolean
600 purple_certificate_pool_store(PurpleCertificatePool *pool, const gchar *id, PurpleCertificate *crt);
601
602 /**
603 * Remove a certificate from a pool
604 *
605 * @param pool Pool to remove from
606 * @param id ID to remove
607 * @return TRUE if the operation succeeded, otherwise FALSE
608 */
609 gboolean
610 purple_certificate_pool_delete(PurpleCertificatePool *pool, const gchar *id);
611
612 /**
613 * Get the list of IDs currently in the pool.
614 *
615 * @param pool Pool to enumerate
616 * @return GList pointing to newly-allocated id strings. Free using
617 * purple_certificate_pool_destroy_idlist()
618 */
619 GList *
620 purple_certificate_pool_get_idlist(PurpleCertificatePool *pool);
621
622 /**
623 * Destroys the result given by purple_certificate_pool_get_idlist()
624 *
625 * @param idlist ID List to destroy
626 */
627 void
628 purple_certificate_pool_destroy_idlist(GList *idlist);
629
630 /*@}*/
631
632 /*****************************************************************************/
633 /** @name Certificate Subsystem API */
634 /*****************************************************************************/
635 /*@{*/
636
637 /**
638 * Initialize the certificate system
639 */
640 void
641 purple_certificate_init(void);
642
643 /**
644 * Un-initialize the certificate system
645 */
646 void
647 purple_certificate_uninit(void);
648
649 /**
650 * Get the Certificate subsystem handle for signalling purposes
651 */
652 gpointer
653 purple_certificate_get_handle(void);
654
655 /** Look up a registered CertificateScheme by name
656 * @param name The scheme name. Case insensitive.
657 * @return Pointer to the located Scheme, or NULL if it isn't found.
658 */
659 PurpleCertificateScheme *
660 purple_certificate_find_scheme(const gchar *name);
661
662 /**
663 * Get all registered CertificateSchemes
664 *
665 * @return GList pointing to all registered CertificateSchemes . This value
666 * is owned by libpurple
667 */
668 GList *
669 purple_certificate_get_schemes(void);
670
671 /** Register a CertificateScheme with libpurple
672 *
673 * No two schemes can be registered with the same name; this function enforces
674 * that.
675 *
676 * @param scheme Pointer to the scheme to register.
677 * @return TRUE if the scheme was successfully added, otherwise FALSE
678 */
679 gboolean
680 purple_certificate_register_scheme(PurpleCertificateScheme *scheme);
681
682 /** Unregister a CertificateScheme from libpurple
683 *
684 * @param scheme Scheme to unregister.
685 * If the scheme is not registered, this is a no-op.
686 *
687 * @return TRUE if the unregister completed successfully
688 */
689 gboolean
690 purple_certificate_unregister_scheme(PurpleCertificateScheme *scheme);
691
692 /** Look up a registered PurpleCertificateVerifier by scheme and name
693 * @param scheme_name Scheme name. Case insensitive.
694 * @param ver_name The verifier name. Case insensitive.
695 * @return Pointer to the located Verifier, or NULL if it isn't found.
696 */
697 PurpleCertificateVerifier *
698 purple_certificate_find_verifier(const gchar *scheme_name, const gchar *ver_name);
699
700 /**
701 * Get the list of registered CertificateVerifiers
702 *
703 * @return GList of all registered PurpleCertificateVerifier. This value
704 * is owned by libpurple
705 */
706 GList *
707 purple_certificate_get_verifiers(void);
708
709 /**
710 * Register a CertificateVerifier with libpurple
711 *
712 * @param vr Verifier to register.
713 * @return TRUE if register succeeded, otherwise FALSE
714 */
715 gboolean
716 purple_certificate_register_verifier(PurpleCertificateVerifier *vr);
717
718 /**
719 * Unregister a CertificateVerifier with libpurple
720 *
721 * @param vr Verifier to unregister.
722 * @return TRUE if unregister succeeded, otherwise FALSE
723 */
724 gboolean
725 purple_certificate_unregister_verifier(PurpleCertificateVerifier *vr);
726
727 /** Look up a registered PurpleCertificatePool by scheme and name
728 * @param scheme_name Scheme name. Case insensitive.
729 * @param pool_name Pool name. Case insensitive.
730 * @return Pointer to the located Pool, or NULL if it isn't found.
731 */
732 PurpleCertificatePool *
733 purple_certificate_find_pool(const gchar *scheme_name, const gchar *pool_name);
734
735 /**
736 * Get the list of registered Pools
737 *
738 * @return GList of all registered PurpleCertificatePool s. This value
739 * is owned by libpurple
740 */
741 GList *
742 purple_certificate_get_pools(void);
743
744 /**
745 * Register a CertificatePool with libpurple and call its init function
746 *
747 * @param pool Pool to register.
748 * @return TRUE if the register succeeded, otherwise FALSE
749 */
750 gboolean
751 purple_certificate_register_pool(PurpleCertificatePool *pool);
752
753 /**
754 * Unregister a CertificatePool with libpurple and call its uninit function
755 *
756 * @param pool Pool to unregister.
757 * @return TRUE if the unregister succeeded, otherwise FALSE
758 */
759 gboolean
760 purple_certificate_unregister_pool(PurpleCertificatePool *pool);
761
762 /*@}*/
763
764
765 #ifdef __cplusplus
766 }
767 #endif /* __cplusplus */
768
769 #endif /* _PURPLE_CERTIFICATE_H */