add callback functionality on certificate verification failure
Based on the differences to libmesode this functionality has been added. It allows a library-user to set a callback for cases where the TLS stack can't verify a received certificate and let the end-user decide what to do. examples/basic implements an example handler of said functionality. Signed-off-by: Steffen Jaeckel <jaeckel-floss@eyet-services.de>
This commit is contained in:
@@ -48,6 +48,7 @@ libstrophe_la_SOURCES = \
|
||||
src/snprintf.c \
|
||||
src/sock.c \
|
||||
src/stanza.c \
|
||||
src/tls.c \
|
||||
src/util.c \
|
||||
src/uuid.c
|
||||
libstrophe_la_SOURCES += \
|
||||
|
||||
@@ -19,6 +19,20 @@
|
||||
#define KA_TIMEOUT 60
|
||||
#define KA_INTERVAL 1
|
||||
|
||||
static void print_tlscert(const xmpp_tlscert_t *cert)
|
||||
{
|
||||
const char *name;
|
||||
size_t n;
|
||||
for (n = 0; n < (unsigned)XMPP_CERT_ELEMENT_MAX; ++n) {
|
||||
printf("\t%32s: %s\n", xmpp_tlscert_get_description(n),
|
||||
xmpp_tlscert_get_string(cert, n));
|
||||
}
|
||||
n = 0;
|
||||
while ((name = xmpp_tlscert_get_dnsname(cert, n++)) != NULL)
|
||||
printf("\t%32s: %s\n", "dnsName", name);
|
||||
printf("PEM:\n%s\n", xmpp_tlscert_get_pem(cert));
|
||||
}
|
||||
|
||||
/* define a handler for connection events */
|
||||
static void conn_handler(xmpp_conn_t *conn,
|
||||
xmpp_conn_event_t status,
|
||||
@@ -37,6 +51,11 @@ static void conn_handler(xmpp_conn_t *conn,
|
||||
secured = xmpp_conn_is_secured(conn);
|
||||
fprintf(stderr, "DEBUG: connection is %s.\n",
|
||||
secured ? "secured" : "NOT secured");
|
||||
if (secured) {
|
||||
xmpp_tlscert_t *cert = xmpp_conn_get_peer_cert(conn);
|
||||
print_tlscert(cert);
|
||||
xmpp_tlscert_free(cert);
|
||||
}
|
||||
xmpp_disconnect(conn);
|
||||
} else {
|
||||
fprintf(stderr, "DEBUG: disconnected\n");
|
||||
@@ -44,6 +63,23 @@ static void conn_handler(xmpp_conn_t *conn,
|
||||
}
|
||||
}
|
||||
|
||||
static int certfail_handler(const xmpp_tlscert_t *cert,
|
||||
const char *const errormsg)
|
||||
{
|
||||
char read_char[16] = {0};
|
||||
printf("Received certificate can't be validated!\n");
|
||||
printf("Reason: %s\n", errormsg);
|
||||
print_tlscert(cert);
|
||||
printf("Do you agree to connect?\n[y(es)|n(o)]: ");
|
||||
fflush(stdout);
|
||||
if (fgets(read_char, sizeof(read_char), stdin) == NULL) {
|
||||
printf("fgets() failed\n");
|
||||
return 0;
|
||||
}
|
||||
printf("\n");
|
||||
return read_char[0] == 'y' || read_char[0] == 'Y';
|
||||
}
|
||||
|
||||
static void usage(int exit_code)
|
||||
{
|
||||
fprintf(stderr,
|
||||
@@ -52,10 +88,15 @@ static void usage(int exit_code)
|
||||
" --jid <jid> The JID to use to authenticate.\n"
|
||||
" --pass <pass> The password of the JID.\n"
|
||||
" --tls-cert <cert> Path to client certificate.\n"
|
||||
" --capath <path> Path to an additional CA trust store "
|
||||
"(directory).\n"
|
||||
" --cafile <path> Path to an additional CA trust store "
|
||||
"(single file).\n"
|
||||
" --tls-key <key> Path to private key.\n\n"
|
||||
" --disable-tls Disable TLS.\n"
|
||||
" --mandatory-tls Deny plaintext connection.\n"
|
||||
" --trust-tls Trust TLS certificate.\n"
|
||||
" --enable-certfail Enable certfail handler.\n"
|
||||
" --legacy-ssl Use old style SSL.\n"
|
||||
" --legacy-auth Allow legacy authentication.\n"
|
||||
" --verbose Increase the verbosity level.\n"
|
||||
@@ -71,9 +112,10 @@ int main(int argc, char **argv)
|
||||
xmpp_ctx_t *ctx;
|
||||
xmpp_conn_t *conn;
|
||||
xmpp_log_t *log;
|
||||
char *jid = NULL, *password = NULL, *cert = NULL, *key = NULL, *host = NULL;
|
||||
char *jid = NULL, *password = NULL, *cert = NULL, *key = NULL, *host = NULL,
|
||||
*capath = NULL, *cafile = NULL;
|
||||
long flags = 0;
|
||||
int tcp_keepalive = 0, verbosity = 0;
|
||||
int tcp_keepalive = 0, verbosity = 0, certfail = 0;
|
||||
int i;
|
||||
unsigned long port = 0;
|
||||
|
||||
@@ -95,6 +137,8 @@ int main(int argc, char **argv)
|
||||
verbosity++;
|
||||
else if (strcmp(argv[i], "--tcp-keepalive") == 0)
|
||||
tcp_keepalive = 1;
|
||||
else if (strcmp(argv[i], "--enable-certfail") == 0)
|
||||
certfail = 1;
|
||||
else if ((strcmp(argv[i], "--jid") == 0) && (++i < argc))
|
||||
jid = argv[i];
|
||||
else if ((strcmp(argv[i], "--pass") == 0) && (++i < argc))
|
||||
@@ -103,6 +147,10 @@ int main(int argc, char **argv)
|
||||
cert = argv[i];
|
||||
else if ((strcmp(argv[i], "--tls-key") == 0) && (++i < argc))
|
||||
key = argv[i];
|
||||
else if ((strcmp(argv[i], "--capath") == 0) && (++i < argc))
|
||||
capath = argv[i];
|
||||
else if ((strcmp(argv[i], "--cafile") == 0) && (++i < argc))
|
||||
cafile = argv[i];
|
||||
else
|
||||
break;
|
||||
}
|
||||
@@ -147,6 +195,13 @@ int main(int argc, char **argv)
|
||||
if (password)
|
||||
xmpp_conn_set_pass(conn, password);
|
||||
|
||||
if (certfail)
|
||||
xmpp_conn_set_certfail_handler(conn, certfail_handler);
|
||||
if (capath)
|
||||
xmpp_conn_set_capath(conn, capath);
|
||||
if (cafile)
|
||||
xmpp_conn_set_cafile(conn, cafile);
|
||||
|
||||
/* initiate connection */
|
||||
if (xmpp_connect_client(conn, host, port, conn_handler, ctx) == XMPP_EOK) {
|
||||
|
||||
|
||||
@@ -169,6 +169,8 @@ struct _xmpp_conn_t {
|
||||
int tls_mandatory;
|
||||
int tls_legacy_ssl;
|
||||
int tls_trust;
|
||||
char *tls_cafile;
|
||||
char *tls_capath;
|
||||
char *tls_client_cert;
|
||||
char *tls_client_key;
|
||||
int tls_failed; /* set when tls fails, so we don't try again */
|
||||
@@ -176,6 +178,7 @@ struct _xmpp_conn_t {
|
||||
mechanisms */
|
||||
int auth_legacy_enabled;
|
||||
int secured; /* set when stream is secured with TLS */
|
||||
xmpp_certfail_handler certfail_handler;
|
||||
|
||||
/* if server returns <bind/> or <session/> we must do them */
|
||||
int bind_required;
|
||||
|
||||
68
src/conn.c
68
src/conn.c
@@ -144,11 +144,14 @@ xmpp_conn_t *xmpp_conn_new(xmpp_ctx_t *ctx)
|
||||
conn->tls_legacy_ssl = 0;
|
||||
conn->tls_trust = 0;
|
||||
conn->tls_failed = 0;
|
||||
conn->tls_cafile = NULL;
|
||||
conn->tls_capath = NULL;
|
||||
conn->tls_client_cert = NULL;
|
||||
conn->tls_client_key = NULL;
|
||||
conn->sasl_support = 0;
|
||||
conn->auth_legacy_enabled = 0;
|
||||
conn->secured = 0;
|
||||
conn->certfail_handler = NULL;
|
||||
|
||||
conn->bind_required = 0;
|
||||
conn->session_required = 0;
|
||||
@@ -345,6 +348,10 @@ int xmpp_conn_release(xmpp_conn_t *conn)
|
||||
xmpp_free(ctx, conn->tls_client_cert);
|
||||
if (conn->tls_client_key)
|
||||
xmpp_free(ctx, conn->tls_client_key);
|
||||
if (conn->tls_cafile)
|
||||
xmpp_free(ctx, conn->tls_cafile);
|
||||
if (conn->tls_capath)
|
||||
xmpp_free(ctx, conn->tls_capath);
|
||||
xmpp_free(ctx, conn);
|
||||
released = 1;
|
||||
}
|
||||
@@ -401,6 +408,64 @@ void xmpp_conn_set_jid(xmpp_conn_t *conn, const char *jid)
|
||||
conn->jid = xmpp_strdup(conn->ctx, jid);
|
||||
}
|
||||
|
||||
/** Set the Handler function which will be called when the TLS stack can't
|
||||
* verify the CA of the server we're trying to connect to.
|
||||
*
|
||||
* @param conn a Strophe connection object
|
||||
* @param hndl certfail Handler function
|
||||
*
|
||||
* @ingroup Connections
|
||||
* @ingroup TLS
|
||||
*/
|
||||
void xmpp_conn_set_certfail_handler(xmpp_conn_t *const conn,
|
||||
xmpp_certfail_handler hndl)
|
||||
{
|
||||
conn->certfail_handler = hndl;
|
||||
}
|
||||
|
||||
/** Set the CAfile
|
||||
*
|
||||
* @param conn a Strophe connection object
|
||||
* @param cert path to a certificate file
|
||||
*
|
||||
* @ingroup Connections
|
||||
* @ingroup TLS
|
||||
*/
|
||||
void xmpp_conn_set_cafile(xmpp_conn_t *const conn, const char *path)
|
||||
{
|
||||
conn->tls_cafile = xmpp_strdup(conn->ctx, path);
|
||||
}
|
||||
|
||||
/** Set the CApath
|
||||
*
|
||||
* @param conn a Strophe connection object
|
||||
* @param cert path to a folder containing certificates
|
||||
*
|
||||
* @ingroup Connections
|
||||
* @ingroup TLS
|
||||
*/
|
||||
void xmpp_conn_set_capath(xmpp_conn_t *const conn, const char *path)
|
||||
{
|
||||
conn->tls_capath = xmpp_strdup(conn->ctx, path);
|
||||
}
|
||||
|
||||
/** Retrieve the peer certificate
|
||||
*
|
||||
* The returned Certificate object must be free'd by calling
|
||||
* \ref xmpp_tlscert_free
|
||||
*
|
||||
* @param conn a Strophe connection object
|
||||
*
|
||||
* @return a Strophe Certificate object
|
||||
*
|
||||
* @ingroup Connections
|
||||
* @ingroup TLS
|
||||
*/
|
||||
xmpp_tlscert_t *xmpp_conn_get_peer_cert(xmpp_conn_t *const conn)
|
||||
{
|
||||
return tls_peer_cert(conn);
|
||||
}
|
||||
|
||||
/** Set the Client Certificate and Private Key that will be bound to the
|
||||
* connection. If any of the both was previously set, it will be discarded.
|
||||
* This should not be used after a connection is created. The function will
|
||||
@@ -412,6 +477,7 @@ void xmpp_conn_set_jid(xmpp_conn_t *conn, const char *jid)
|
||||
* @param key path to a private key file
|
||||
*
|
||||
* @ingroup Connections
|
||||
* @ingroup TLS
|
||||
*/
|
||||
void xmpp_conn_set_client_cert(xmpp_conn_t *const conn,
|
||||
const char *const cert,
|
||||
@@ -433,6 +499,7 @@ void xmpp_conn_set_client_cert(xmpp_conn_t *const conn,
|
||||
* @return the number of xmppAddr entries in the client certificate
|
||||
*
|
||||
* @ingroup Connections
|
||||
* @ingroup TLS
|
||||
*/
|
||||
unsigned int xmpp_conn_cert_xmppaddr_num(xmpp_conn_t *const conn)
|
||||
{
|
||||
@@ -447,6 +514,7 @@ unsigned int xmpp_conn_cert_xmppaddr_num(xmpp_conn_t *const conn)
|
||||
* @return a string containing the xmppAddr or NULL if n is out of range
|
||||
*
|
||||
* @ingroup Connections
|
||||
* @ingroup TLS
|
||||
*/
|
||||
char *xmpp_conn_cert_xmppaddr(xmpp_conn_t *const conn, unsigned int n)
|
||||
{
|
||||
|
||||
214
src/tls.c
Normal file
214
src/tls.c
Normal file
@@ -0,0 +1,214 @@
|
||||
/* tls.c
|
||||
** strophe XMPP client library -- generic TLS functions
|
||||
**
|
||||
** Copyright (C) 2021 Steffen Jaeckel <jaeckel-floss@eyet-services.de>
|
||||
**
|
||||
** This software is provided AS-IS with no warranty, either express
|
||||
** or implied.
|
||||
**
|
||||
** This program is dual licensed under the MIT and GPLv3 licenses.
|
||||
*/
|
||||
|
||||
/** @file
|
||||
* Generic TLS functionality.
|
||||
*/
|
||||
|
||||
/** @defgroup TLS SSL/TLS specific functionality
|
||||
* These functions provide SSL/TLS specific functionality.
|
||||
*/
|
||||
|
||||
#include <errno.h>
|
||||
#include <stdarg.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "strophe.h"
|
||||
|
||||
#include "common.h"
|
||||
|
||||
struct _dnsname_t {
|
||||
char **data;
|
||||
size_t cur, max;
|
||||
};
|
||||
|
||||
const size_t tlscert_dnsnames_increment = 4;
|
||||
|
||||
/** Get the Strophe context which is assigned to this certificate.
|
||||
*
|
||||
* @param cert a Strophe TLS certificate object
|
||||
*
|
||||
* @return the Strophe context object where this certificate originates from
|
||||
*
|
||||
* @ingroup TLS
|
||||
*/
|
||||
xmpp_ctx_t *xmpp_tlscert_get_ctx(const xmpp_tlscert_t *cert)
|
||||
{
|
||||
return cert->ctx;
|
||||
}
|
||||
|
||||
/** Get the Strophe connection which is assigned to this certificate.
|
||||
*
|
||||
* @param cert a Strophe TLS certificate object
|
||||
*
|
||||
* @return the Strophe connection object where this certificate originates from
|
||||
*
|
||||
* @ingroup TLS
|
||||
*/
|
||||
xmpp_conn_t *xmpp_tlscert_get_conn(const xmpp_tlscert_t *cert)
|
||||
{
|
||||
return cert->conn;
|
||||
}
|
||||
|
||||
/** Get the complete PEM of this certificate.
|
||||
*
|
||||
* @param cert a Strophe TLS certificate object
|
||||
*
|
||||
* @return a string containing the PEM of this certificate
|
||||
*
|
||||
* @ingroup TLS
|
||||
*/
|
||||
const char *xmpp_tlscert_get_pem(const xmpp_tlscert_t *cert)
|
||||
{
|
||||
return cert->pem;
|
||||
}
|
||||
|
||||
/** Get the dnsName entries out of the SubjectAlternativeNames.
|
||||
*
|
||||
* Note: Max. `MAX_NUM_DNSNAMES` are supported.
|
||||
*
|
||||
* @param cert a Strophe TLS certificate object
|
||||
* @param n which dnsName entry
|
||||
*
|
||||
* @return a string with the n'th dnsName
|
||||
*
|
||||
* @ingroup TLS
|
||||
*/
|
||||
const char *xmpp_tlscert_get_dnsname(const xmpp_tlscert_t *cert, size_t n)
|
||||
{
|
||||
if (n >= cert->dnsnames->cur)
|
||||
return NULL;
|
||||
return cert->dnsnames->data[n];
|
||||
}
|
||||
|
||||
/** Get various parts of the certificate as String.
|
||||
*
|
||||
* c.f. \ref xmpp_cert_element_t for details.
|
||||
*
|
||||
* @param cert a Strophe TLS certificate object
|
||||
* @param elmnt which part of the certificate
|
||||
*
|
||||
* @return a string with the part of the certificate
|
||||
*
|
||||
* @ingroup TLS
|
||||
*/
|
||||
const char *xmpp_tlscert_get_string(const xmpp_tlscert_t *cert,
|
||||
xmpp_cert_element_t elmnt)
|
||||
{
|
||||
if (elmnt >= XMPP_CERT_ELEMENT_MAX)
|
||||
return NULL;
|
||||
return cert->elements[elmnt];
|
||||
}
|
||||
|
||||
/** Get a descriptive string for each xmpp_cert_element_t.
|
||||
*
|
||||
* c.f. \ref xmpp_cert_element_t for details.
|
||||
*
|
||||
* @param cert a Strophe TLS certificate object
|
||||
* @param elmnt which element
|
||||
*
|
||||
* @return a string with the description
|
||||
*
|
||||
* @ingroup TLS
|
||||
*/
|
||||
const char *xmpp_tlscert_get_description(xmpp_cert_element_t elmnt)
|
||||
{
|
||||
static const char *descriptions[] = {
|
||||
"X.509 Version",
|
||||
"SerialNumber",
|
||||
"Subject",
|
||||
"Issuer",
|
||||
"Issued On",
|
||||
"Expires On",
|
||||
"Public Key Algorithm",
|
||||
"Certificate Signature Algorithm",
|
||||
"Fingerprint SHA-1",
|
||||
"Fingerprint SHA-256",
|
||||
};
|
||||
if (elmnt >= XMPP_CERT_ELEMENT_MAX)
|
||||
return NULL;
|
||||
return descriptions[elmnt];
|
||||
}
|
||||
|
||||
/** Allocate and initialize a Strophe TLS certificate object.
|
||||
*
|
||||
* @param ctx a Strophe context object
|
||||
*
|
||||
* @return a certificate object or NULL
|
||||
*/
|
||||
xmpp_tlscert_t *tlscert_new(xmpp_ctx_t *ctx)
|
||||
{
|
||||
xmpp_tlscert_t *tlscert = xmpp_alloc(ctx, sizeof(*tlscert));
|
||||
if (!tlscert)
|
||||
return NULL;
|
||||
memset(tlscert, 0, sizeof(*tlscert));
|
||||
|
||||
tlscert->dnsnames = xmpp_alloc(ctx, sizeof(*tlscert->dnsnames));
|
||||
if (!tlscert->dnsnames) {
|
||||
xmpp_free(ctx, tlscert);
|
||||
return NULL;
|
||||
}
|
||||
memset(tlscert->dnsnames, 0, sizeof(*tlscert->dnsnames));
|
||||
|
||||
tlscert->ctx = ctx;
|
||||
|
||||
return tlscert;
|
||||
}
|
||||
|
||||
/** Free a certificate object.
|
||||
*
|
||||
* @param cert a Strophe TLS certificate object
|
||||
*
|
||||
* @ingroup TLS
|
||||
*/
|
||||
void xmpp_tlscert_free(xmpp_tlscert_t *cert)
|
||||
{
|
||||
size_t n;
|
||||
for (n = 0; n < ARRAY_SIZE(cert->elements); ++n) {
|
||||
if (cert->elements[n])
|
||||
xmpp_free(cert->ctx, cert->elements[n]);
|
||||
}
|
||||
if (cert->dnsnames->data) {
|
||||
for (n = 0; n < cert->dnsnames->cur; ++n) {
|
||||
if (cert->dnsnames->data[n])
|
||||
xmpp_free(cert->ctx, cert->dnsnames->data[n]);
|
||||
}
|
||||
}
|
||||
xmpp_free(cert->ctx, cert->dnsnames->data);
|
||||
xmpp_free(cert->ctx, cert->dnsnames);
|
||||
if (cert->pem)
|
||||
xmpp_free(cert->ctx, cert->pem);
|
||||
xmpp_free(cert->ctx, cert);
|
||||
}
|
||||
|
||||
/** Add a dnsName to the Strophe TLS certificate object.
|
||||
*
|
||||
* @param cert a Strophe TLS certificate object
|
||||
* @param dnsname dnsName that shall be stored
|
||||
*
|
||||
* @return classic Unix style - 0=success, 1=error
|
||||
*/
|
||||
int tlscert_add_dnsname(xmpp_tlscert_t *cert, const char *dnsname)
|
||||
{
|
||||
if ((cert->dnsnames->cur + 1) >= cert->dnsnames->max) {
|
||||
char **dnsnames =
|
||||
xmpp_realloc(cert->ctx, cert->dnsnames->data,
|
||||
(cert->dnsnames->max + tlscert_dnsnames_increment) *
|
||||
sizeof(char **));
|
||||
if (!dnsnames)
|
||||
return 1;
|
||||
cert->dnsnames->data = dnsnames;
|
||||
cert->dnsnames->max += tlscert_dnsnames_increment;
|
||||
}
|
||||
cert->dnsnames->data[cert->dnsnames->cur++] =
|
||||
xmpp_strdup(cert->ctx, dnsname);
|
||||
return 0;
|
||||
}
|
||||
14
src/tls.h
14
src/tls.h
@@ -21,6 +21,16 @@
|
||||
|
||||
typedef struct _tls tls_t;
|
||||
|
||||
typedef struct _dnsname_t dnsname_t;
|
||||
|
||||
struct _xmpp_tlscert_t {
|
||||
xmpp_ctx_t *ctx;
|
||||
xmpp_conn_t *conn;
|
||||
char *pem;
|
||||
char *elements[XMPP_CERT_ELEMENT_MAX];
|
||||
dnsname_t *dnsnames;
|
||||
};
|
||||
|
||||
void tls_initialize(void);
|
||||
void tls_shutdown(void);
|
||||
|
||||
@@ -30,6 +40,7 @@ void tls_free(tls_t *tls);
|
||||
char *tls_id_on_xmppaddr(xmpp_conn_t *conn, unsigned int n);
|
||||
unsigned int tls_id_on_xmppaddr_num(xmpp_conn_t *conn);
|
||||
|
||||
xmpp_tlscert_t *tls_peer_cert(xmpp_conn_t *conn);
|
||||
int tls_set_credentials(tls_t *tls, const char *cafilename);
|
||||
|
||||
int tls_start(tls_t *tls);
|
||||
@@ -44,4 +55,7 @@ int tls_write(tls_t *tls, const void *buff, size_t len);
|
||||
int tls_clear_pending_write(tls_t *tls);
|
||||
int tls_is_recoverable(int error);
|
||||
|
||||
xmpp_tlscert_t *tlscert_new(xmpp_ctx_t *ctx);
|
||||
int tlscert_add_dnsname(xmpp_tlscert_t *cert, const char *dnsname);
|
||||
|
||||
#endif /* __LIBSTROPHE_TLS_H__ */
|
||||
|
||||
58
strophe.h
58
strophe.h
@@ -122,6 +122,8 @@ typedef struct _xmpp_log_t xmpp_log_t;
|
||||
/* opaque run time context containing the above hooks */
|
||||
typedef struct _xmpp_ctx_t xmpp_ctx_t;
|
||||
|
||||
typedef struct _xmpp_tlscert_t xmpp_tlscert_t;
|
||||
|
||||
xmpp_ctx_t *xmpp_ctx_new(const xmpp_mem_t *mem, const xmpp_log_t *log);
|
||||
void xmpp_ctx_free(xmpp_ctx_t *ctx);
|
||||
|
||||
@@ -215,6 +217,24 @@ typedef enum {
|
||||
XMPP_SE_XML_NOT_WELL_FORMED
|
||||
} xmpp_error_type_t;
|
||||
|
||||
/** Certificate Elements
|
||||
*
|
||||
* @ingroup TLS
|
||||
*/
|
||||
typedef enum {
|
||||
XMPP_CERT_VERSION, /**< X.509 Version */
|
||||
XMPP_CERT_SERIALNUMBER, /**< SerialNumber */
|
||||
XMPP_CERT_SUBJECT, /**< Subject */
|
||||
XMPP_CERT_ISSUER, /**< Issuer */
|
||||
XMPP_CERT_NOTBEFORE, /**< Issued on */
|
||||
XMPP_CERT_NOTAFTER, /**< Expires on */
|
||||
XMPP_CERT_KEYALG, /**< Public Key Algorithm */
|
||||
XMPP_CERT_SIGALG, /**< Certificate Signature Algorithm */
|
||||
XMPP_CERT_FINGERPRINT_SHA1, /**< Fingerprint SHA-1 */
|
||||
XMPP_CERT_FINGERPRINT_SHA256, /**< Fingerprint SHA-256 */
|
||||
XMPP_CERT_ELEMENT_MAX /**< Last element of the enum */
|
||||
} xmpp_cert_element_t;
|
||||
|
||||
typedef struct {
|
||||
xmpp_error_type_t type;
|
||||
char *text;
|
||||
@@ -227,6 +247,28 @@ typedef void (*xmpp_conn_handler)(xmpp_conn_t *conn,
|
||||
xmpp_stream_error_t *stream_error,
|
||||
void *userdata);
|
||||
|
||||
/** The Handler function which will be called when the TLS stack can't
|
||||
* verify the authenticity of a Certificate that gets presented by
|
||||
* the server we're trying to connect to.
|
||||
*
|
||||
* When this function is called and details of the `cert` have to be
|
||||
* kept, please copy them yourself. The `cert` object will be free'd
|
||||
* automatically when this function returns.
|
||||
*
|
||||
* NB: `errormsg` is specific per certificate on OpenSSL and the same
|
||||
* for all certificates on GnuTLS.
|
||||
*
|
||||
* @param cert a Strophe certificate object
|
||||
* @param errormsg The error that caused this.
|
||||
*
|
||||
* @return 0 if the connection attempt should be terminated,
|
||||
* 1 if the connection should be established.
|
||||
*
|
||||
* @ingroup TLS
|
||||
*/
|
||||
typedef int (*xmpp_certfail_handler)(const xmpp_tlscert_t *cert,
|
||||
const char *const errormsg);
|
||||
|
||||
void xmpp_send_error(xmpp_conn_t *conn, xmpp_error_type_t type, char *text);
|
||||
xmpp_conn_t *xmpp_conn_new(xmpp_ctx_t *ctx);
|
||||
xmpp_conn_t *xmpp_conn_clone(xmpp_conn_t *conn);
|
||||
@@ -237,6 +279,11 @@ int xmpp_conn_set_flags(xmpp_conn_t *conn, long flags);
|
||||
const char *xmpp_conn_get_jid(const xmpp_conn_t *conn);
|
||||
const char *xmpp_conn_get_bound_jid(const xmpp_conn_t *conn);
|
||||
void xmpp_conn_set_jid(xmpp_conn_t *conn, const char *jid);
|
||||
void xmpp_conn_set_cafile(xmpp_conn_t *const conn, const char *path);
|
||||
void xmpp_conn_set_capath(xmpp_conn_t *const conn, const char *path);
|
||||
void xmpp_conn_set_certfail_handler(xmpp_conn_t *const conn,
|
||||
xmpp_certfail_handler hndl);
|
||||
xmpp_tlscert_t *xmpp_conn_get_peer_cert(xmpp_conn_t *const conn);
|
||||
void xmpp_conn_set_client_cert(xmpp_conn_t *conn,
|
||||
const char *cert,
|
||||
const char *key);
|
||||
@@ -437,6 +484,17 @@ void xmpp_run(xmpp_ctx_t *ctx);
|
||||
void xmpp_stop(xmpp_ctx_t *ctx);
|
||||
void xmpp_ctx_set_timeout(xmpp_ctx_t *ctx, unsigned long timeout);
|
||||
|
||||
/* TLS certificates */
|
||||
|
||||
xmpp_ctx_t *xmpp_tlscert_get_ctx(const xmpp_tlscert_t *cert);
|
||||
xmpp_conn_t *xmpp_tlscert_get_conn(const xmpp_tlscert_t *cert);
|
||||
const char *xmpp_tlscert_get_pem(const xmpp_tlscert_t *cert);
|
||||
const char *xmpp_tlscert_get_dnsname(const xmpp_tlscert_t *cert, size_t n);
|
||||
const char *xmpp_tlscert_get_string(const xmpp_tlscert_t *cert,
|
||||
xmpp_cert_element_t elmnt);
|
||||
const char *xmpp_tlscert_get_description(xmpp_cert_element_t elmnt);
|
||||
void xmpp_tlscert_free(xmpp_tlscert_t *cert);
|
||||
|
||||
/* UUID */
|
||||
|
||||
char *xmpp_uuid_gen(xmpp_ctx_t *ctx);
|
||||
|
||||
Reference in New Issue
Block a user