Mercurial > pidgin
view libpurple/certificate.h @ 19001:b207701cb5a3
- Wrote the logic for the "previously unknown host" condition in
tls_cached Verifier
author | William Ehlhardt <williamehlhardt@gmail.com> |
---|---|
date | Sun, 08 Jul 2007 02:25:17 +0000 |
parents | 47b06daea9d1 |
children | dc60287ce426 |
line wrap: on
line source
/** * @file certificate.h Public-Key Certificate API * @ingroup core */ /* * * purple * * Purple is the legal property of its developers, whose names are too numerous * to list here. Please refer to the COPYRIGHT file distributed with this * source distribution. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef _PURPLE_CERTIFICATE_H #define _PURPLE_CERTIFICATE_H #include <glib.h> #ifdef __cplusplus extern "C" { #endif /* __cplusplus */ typedef enum { PURPLE_CERTIFICATE_INVALID = 0, PURPLE_CERTIFICATE_VALID = 1 } PurpleCertificateVerificationStatus; typedef struct _PurpleCertificate PurpleCertificate; typedef struct _PurpleCertificatePool PurpleCertificatePool; typedef struct _PurpleCertificateScheme PurpleCertificateScheme; typedef struct _PurpleCertificateVerifier PurpleCertificateVerifier; typedef struct _PurpleCertificateVerificationRequest PurpleCertificateVerificationRequest; /** * Callback function for the results of a verification check * @param st Status code * @param userdata User-defined data */ typedef void (*PurpleCertificateVerifiedCallback) (PurpleCertificateVerificationStatus st, gpointer userdata); /** A certificate instance * * An opaque data structure representing a single certificate under some * CertificateScheme */ struct _PurpleCertificate { /** Scheme this certificate is under */ PurpleCertificateScheme * scheme; /** Opaque pointer to internal data */ gpointer data; }; /** * Database for retrieval or storage of Certificates * * More or less a hash table; all lookups and writes are controlled by a string * key. */ struct _PurpleCertificatePool { /** Scheme this Pool operates for */ gchar *scheme_name; /** Internal name to refer to the pool by */ gchar *name; /** User-friendly name for this type * ex: N_("SSL Servers") * When this is displayed anywhere, it should be i18ned * ex: _(pool->fullname) */ gchar *fullname; /** Internal pool data */ gpointer data; /** * Set up the Pool's internal state * * Upon calling purple_certificate_register_pool() , this function will * be called. May be NULL. * @return TRUE if the initialization succeeded, otherwise FALSE */ gboolean (* init)(void); /** * Uninit the Pool's internal state * * Will be called by purple_certificate_unregister_pool() . May be NULL */ void (* uninit)(void); /** Check for presence of a certificate in the pool using unique ID */ gboolean (* cert_in_pool)(const gchar *id); /** Retrieve a PurpleCertificate from the pool */ PurpleCertificate * (* get_cert)(const gchar *id); /** Add a certificate to the pool. Must overwrite any other * certificates sharing the same ID in the pool. * @return TRUE if the operation succeeded, otherwise FALSE */ gboolean (* put_cert)(const gchar *id, PurpleCertificate *crt); }; /** A certificate type * * A CertificateScheme must implement all of the fields in the structure, * and register it using purple_certificate_register_scheme() * * There may be only ONE CertificateScheme provided for each certificate * type, as specified by the "name" field. */ struct _PurpleCertificateScheme { /** Name of the certificate type * ex: "x509", "pgp", etc. * This must be globally unique - you may not register more than one * CertificateScheme of the same name at a time. */ gchar * name; /** User-friendly name for this type * ex: N_("X.509 Certificates") * When this is displayed anywhere, it should be i18ned * ex: _(scheme->fullname) */ gchar * fullname; /** Imports a certificate from a file * * @param filename File to import the certificate from * @return Pointer to the newly allocated Certificate struct * or NULL on failure. */ PurpleCertificate * (* import_certificate)(const gchar * filename); /** * Exports a certificate to a file * * @param filename File to export the certificate to * @param crt Certificate to export * @return TRUE if the export succeeded, otherwise FALSE * @see purple_certificate_export() */ gboolean (* export_certificate)(const gchar *filename, PurpleCertificate *crt); /** Destroys and frees a Certificate structure * * Destroys a Certificate's internal data structures and calls * free(crt) * * @param crt Certificate instance to be destroyed. It WILL NOT be * destroyed if it is not of the correct * CertificateScheme. Can be NULL */ void (* destroy_certificate)(PurpleCertificate * crt); /** * Retrieves the certificate public key fingerprint using SHA1 * * @param crt Certificate instance * @return Binary representation of SHA1 hash - must be freed using * g_byte_array_free() */ GByteArray * (* get_fingerprint_sha1)(PurpleCertificate *crt); /** * Reads "who the certificate is assigned to" * * For SSL X.509 certificates, this is something like * "gmail.com" or "jabber.org" * * @param crt Certificate instance * @return Newly allocated string specifying "whose certificate this * is" */ gchar * (* get_certificate_subject)(PurpleCertificate *crt); /** * Retrieves a unique certificate identifier * * @param crt Certificate instance * @return Newly allocated string that can be used to uniquely * identify the certificate. */ gchar * (* get_unique_id)(PurpleCertificate *crt); /** * Retrieves a unique identifier for the certificate's issuer * * @param crt Certificate instance * @return Newly allocated string that can be used to uniquely * identify the issuer's certificate. */ gchar * (* get_issuer_unique_id)(PurpleCertificate *crt); /** * Gets the certificate subject's name * * For X.509, this is the "Common Name" field, as we're only using it * for hostname verification at the moment * * @see purple_certificate_get_subject_name() * * @param crt Certificate instance * @return Newly allocated string with the certificate subject. */ gchar * (* get_subject_name)(PurpleCertificate *crt); /* TODO: Fill out this structure */ }; /** A set of operations used to provide logic for verifying a Certificate's * authenticity. * * A Verifier provider must fill out these fields, then register it using * purple_certificate_register_verifier() * * The (scheme_name, name) value must be unique for each Verifier - you may not * register more than one Verifier of the same name for each Scheme */ struct _PurpleCertificateVerifier { /** Name of the scheme this Verifier operates on * * The scheme will be looked up by name when a Request is generated * using this Verifier */ gchar *scheme_name; /** Name of the Verifier - case insensitive */ gchar *name; /** * Start the verification process * * To be called from purple_certificate_verify once it has * constructed the request. This will use the information in the * given VerificationRequest to check the certificate and callback * the requester with the verification results. * * @param vrq Request to process */ void (* start_verification)(PurpleCertificateVerificationRequest *vrq); /** * Destroy a completed Request under this Verifier * The function pointed to here is only responsible for cleaning up * whatever PurpleCertificateVerificationRequest::data points to. * It should not call free(vrq) * * @param vrq Request to destroy */ void (* destroy_request)(PurpleCertificateVerificationRequest *vrq); }; /** Structure for a single certificate request * * Useful for keeping track of the state of a verification that involves * several steps */ struct _PurpleCertificateVerificationRequest { /** Reference to the verification logic used */ PurpleCertificateVerifier *verifier; /** Reference to the scheme used. * * This is looked up from the Verifier when the Request is generated */ PurpleCertificateScheme *scheme; /** * Name to check that the certificate is issued to * * For X.509 certificates, this is the Common Name */ gchar *subject_name; /** List of certificates in the chain to be verified (such as that returned by purple_ssl_get_peer_certificates ) * * This is most relevant for X.509 certificates used in SSL sessions. * The list order should be: certificate, issuer, issuer's issuer, etc. */ GList *cert_chain; /** Internal data used by the Verifier code */ gpointer data; /** Function to call with the verification result */ PurpleCertificateVerifiedCallback cb; /** Data to pass to the post-verification callback */ gpointer cb_data; }; /*****************************************************************************/ /** @name Certificate Verification Functions */ /*****************************************************************************/ /*@{*/ /** * Constructs a verification request and passed control to the specified Verifier * * It is possible that the callback will be called immediately upon calling * this function. Plan accordingly. * * @param verifier Verification logic to use. * @see purple_certificate_find_verifier() * * @param subject_name Name that should match the first certificate in the * chain for the certificate to be valid. Will be strdup'd * into the Request struct * * @param cert_chain Certificate chain to check. If there is more than one * certificate in the chain (X.509), the peer's * certificate comes first, then the issuer/signer's * certificate, etc. * * @param cb Callback function to be called with whether the * certificate was approved or not. * @param cb_data User-defined data for the above. */ void purple_certificate_verify (PurpleCertificateVerifier *verifier, const gchar *subject_name, GList *cert_chain, PurpleCertificateVerifiedCallback cb, gpointer cb_data); /** * Disposes of a VerificationRequest once it is complete * * @param vrq Request to destroy. Will be free()'d. * The certificate chain involved will also be destroyed. */ void purple_certificate_verify_destroy (PurpleCertificateVerificationRequest *vrq); /*@}*/ /*****************************************************************************/ /** @name Certificate Functions */ /*****************************************************************************/ /*@{*/ /** * Destroys and free()'s a Certificate * * @param crt Instance to destroy. May be NULL. */ void purple_certificate_destroy (PurpleCertificate *crt); /** * Destroy an entire list of Certificate instances and the containing list * * @param crt_list List of certificates to destroy. May be NULL. */ void purple_certificate_destroy_list (GList * crt_list); /** * Imports a PurpleCertificate from a file * * @param scheme Scheme to import under * @param filename File path to import from * @return Pointer to a new PurpleCertificate, or NULL on failure */ PurpleCertificate * purple_certificate_import(PurpleCertificateScheme *scheme, const gchar *filename); /** * Exports a PurpleCertificate to a file * * @param filename File to export the certificate to * @param crt Certificate to export * @return TRUE if the export succeeded, otherwise FALSE */ gboolean purple_certificate_export(const gchar *filename, PurpleCertificate *crt); /** * Retrieves the certificate public key fingerprint using SHA1. * * @param crt Certificate instance * @return Binary representation of the hash. You are responsible for free()ing * this. * @see purple_base16_encode_chunked() */ GByteArray * purple_certificate_get_fingerprint_sha1(PurpleCertificate *crt); /** * Gets the certificate subject's name * * For X.509, this is the "Common Name" field, as we're only using it * for hostname verification at the moment * * @param crt Certificate instance * @return Newly allocated string with the certificate subject. */ gchar * purple_certificate_get_subject_name(PurpleCertificate *crt); /*@}*/ /*****************************************************************************/ /** @name Certificate Pool Functions */ /*****************************************************************************/ /*@{*/ /** * Helper function for generating file paths in ~/.purple/certificates for * CertificatePools that use them. * * @todo Passing in filesystem-unfriendly characters will cause breakage! * @param pool CertificatePool to build a path for * @param id Key to look up a Certificate by. May be NULL. * @return A newly allocated path of the form * ~/.purple/certificates/scheme_name/pool_name/unique_id */ gchar * purple_certificate_pool_mkpath(PurpleCertificatePool *pool, const gchar *id); /** * Check for presence of an ID in a pool. * @param pool Pool to look in * @param id ID to look for * @return TRUE if the ID is in the pool, else FALSE */ gboolean purple_certificate_pool_contains(PurpleCertificatePool *pool, const gchar *id); /** * Retrieve a certificate from a pool. * @param pool Pool to fish in * @param id ID to look up * @return Retrieved certificate, or NULL if it wasn't there */ PurpleCertificate * purple_certificate_pool_retrieve(PurpleCertificatePool *pool, const gchar *id); /** * Add a certificate to a pool * * Any pre-existing certificate of the same ID will be overwritten. * * @param pool Pool to add to * @param id ID to store the certificate with * @param crt Certificate to store * @return TRUE if the operation succeeded, otherwise FALSE */ gboolean purple_certificate_pool_store(PurpleCertificatePool *pool, const gchar *id, PurpleCertificate *crt); /*@}*/ /*****************************************************************************/ /** @name Certificate Subsystem API */ /*****************************************************************************/ /*@{*/ /** * Initialize the certificate system */ void purple_certificate_init(void); /** * Un-initialize the certificate system */ void purple_certificate_uninit(void); /** Look up a registered CertificateScheme by name * @param name The scheme name. Case insensitive. * @return Pointer to the located Scheme, or NULL if it isn't found. */ PurpleCertificateScheme * purple_certificate_find_scheme(const gchar *name); /** Register a CertificateScheme with libpurple * * No two schemes can be registered with the same name; this function enforces * that. * * @param scheme Pointer to the scheme to register. * @return TRUE if the scheme was successfully added, otherwise FALSE */ gboolean purple_certificate_register_scheme(PurpleCertificateScheme *scheme); /** Unregister a CertificateScheme from libpurple * * @param scheme Scheme to unregister. * If the scheme is not registered, this is a no-op. * * @return TRUE if the unregister completed successfully */ gboolean purple_certificate_unregister_scheme(PurpleCertificateScheme *scheme); /** Look up a registered PurpleCertificateVerifier by scheme and name * @param scheme_name Scheme name. Case insensitive. * @param ver_name The verifier name. Case insensitive. * @return Pointer to the located Verifier, or NULL if it isn't found. */ PurpleCertificateVerifier * purple_certificate_find_verifier(const gchar *scheme_name, const gchar *ver_name); /** * Register a CertificateVerifier with libpurple * * @param vr Verifier to register. * @return TRUE if register succeeded, otherwise FALSE */ gboolean purple_certificate_register_verifier(PurpleCertificateVerifier *vr); /** * Unregister a CertificateVerifier with libpurple * * @param vr Verifier to unregister. * @return TRUE if unregister succeeded, otherwise FALSE */ gboolean purple_certificate_unregister_verifier(PurpleCertificateVerifier *vr); /** Look up a registered PurpleCertificatePool by scheme and name * @param scheme_name Scheme name. Case insensitive. * @param pool_name Pool name. Case insensitive. * @return Pointer to the located Pool, or NULL if it isn't found. */ PurpleCertificatePool * purple_certificate_find_pool(const gchar *scheme_name, const gchar *pool_name); /** * Register a CertificatePool with libpurple and call its init function * * @param pool Pool to register. * @return TRUE if the register succeeded, otherwise FALSE */ gboolean purple_certificate_register_pool(PurpleCertificatePool *pool); /** * Unregister a CertificatePool with libpurple and call its uninit function * * @param pool Pool to unregister. * @return TRUE if the unregister succeeded, otherwise FALSE */ gboolean purple_certificate_unregister_pool(PurpleCertificatePool *pool); /*@}*/ #ifdef __cplusplus } #endif /* __cplusplus */ #endif /* _PURPLE_CERTIFICATE_H */