mirror of
https://github.com/strophe/libstrophe.git
synced 2026-07-17 19:36:22 +00:00
Add support to retrieve the fingerprint of a public key from a cert.
Related-to: https://github.com/profanity-im/profanity/issues/2069 Signed-off-by: Steffen Jaeckel <s@jaeckel.eu>
This commit is contained in:
11
src/common.h
11
src/common.h
@@ -29,6 +29,17 @@
|
||||
#include "parser.h"
|
||||
#include "snprintf.h"
|
||||
|
||||
/** Define your own `STROPHE_STATIC_ASSERT` if your compiler doesn't support one
|
||||
* of the below ones or define as noop if your compiler provides no replacement.
|
||||
*/
|
||||
#if !defined(STROPHE_STATIC_ASSERT)
|
||||
#if (__STDC_VERSION__ >= 202000L)
|
||||
#define STROPHE_STATIC_ASSERT(cond, msg) static_assert(cond, msg)
|
||||
#else
|
||||
#define STROPHE_STATIC_ASSERT(cond, msg) _Static_assert(cond, msg)
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/** handlers **/
|
||||
#if (__STDC_VERSION__ >= 202000L)
|
||||
typedef void *xmpp_void_handler;
|
||||
|
||||
@@ -164,9 +164,13 @@ const char *xmpp_tlscert_get_description(xmpp_cert_element_t elmnt)
|
||||
"Expires On",
|
||||
"Public Key Algorithm",
|
||||
"Certificate Signature Algorithm",
|
||||
"Fingerprint SHA-1",
|
||||
"Fingerprint SHA-256",
|
||||
"Certificate Fingerprint SHA-1",
|
||||
"Certificate Fingerprint SHA-256",
|
||||
"Public Key Fingerprint SHA-256",
|
||||
};
|
||||
STROPHE_STATIC_ASSERT(
|
||||
ARRAY_SIZE(descriptions) == XMPP_CERT_ELEMENT_MAX,
|
||||
"descriptions don't match the number of enum elements");
|
||||
if (elmnt < 0 || elmnt >= XMPP_CERT_ELEMENT_MAX)
|
||||
return NULL;
|
||||
return descriptions[elmnt];
|
||||
|
||||
@@ -334,6 +334,12 @@ static xmpp_tlscert_t *_x509_to_tlscert(xmpp_ctx_t *ctx, gnutls_x509_crt_t cert)
|
||||
gnutls_x509_crt_get_fingerprint(cert, GNUTLS_DIG_SHA256, smallbuf, &size);
|
||||
hex_encode(buf, smallbuf, size);
|
||||
tlscert->elements[XMPP_CERT_FINGERPRINT_SHA256] = strophe_strdup(ctx, buf);
|
||||
size = sizeof(smallbuf);
|
||||
gnutls_x509_crt_get_key_id(cert, GNUTLS_KEYID_USE_SHA256, (void *)smallbuf,
|
||||
&size);
|
||||
hex_encode(buf, smallbuf, size);
|
||||
tlscert->elements[XMPP_CERT_PUBKEY_FINGERPRINT_SHA256] =
|
||||
strophe_strdup(ctx, buf);
|
||||
|
||||
strophe_snprintf(buf, sizeof(buf), "%d", gnutls_x509_crt_get_version(cert));
|
||||
tlscert->elements[XMPP_CERT_VERSION] = strophe_strdup(ctx, buf);
|
||||
|
||||
@@ -376,18 +376,26 @@ _get_fingerprint(const xmpp_ctx_t *ctx, X509 *err_cert, xmpp_cert_element_t el)
|
||||
{
|
||||
unsigned char buf[EVP_MAX_MD_SIZE];
|
||||
unsigned int len;
|
||||
int (*digest_fn)(const X509 *data, const EVP_MD *type, unsigned char *md,
|
||||
unsigned int *len);
|
||||
const EVP_MD *digest;
|
||||
switch (el) {
|
||||
case XMPP_CERT_FINGERPRINT_SHA1:
|
||||
digest_fn = X509_digest;
|
||||
digest = EVP_sha1();
|
||||
break;
|
||||
case XMPP_CERT_FINGERPRINT_SHA256:
|
||||
digest_fn = X509_digest;
|
||||
digest = EVP_sha256();
|
||||
break;
|
||||
case XMPP_CERT_PUBKEY_FINGERPRINT_SHA256:
|
||||
digest_fn = X509_pubkey_digest;
|
||||
digest = EVP_sha256();
|
||||
break;
|
||||
default:
|
||||
return NULL;
|
||||
}
|
||||
if (X509_digest(err_cert, digest, buf, &len) != 0) {
|
||||
if (digest_fn(err_cert, digest, buf, &len) != 0) {
|
||||
char fingerprint[4 * EVP_MAX_MD_SIZE];
|
||||
hex_encode(fingerprint, buf, len);
|
||||
return strophe_strdup(ctx, fingerprint);
|
||||
@@ -475,6 +483,8 @@ static xmpp_tlscert_t *_x509_to_tlscert(xmpp_ctx_t *ctx, X509 *cert)
|
||||
_get_fingerprint(ctx, cert, XMPP_CERT_FINGERPRINT_SHA1);
|
||||
tlscert->elements[XMPP_CERT_FINGERPRINT_SHA256] =
|
||||
_get_fingerprint(ctx, cert, XMPP_CERT_FINGERPRINT_SHA256);
|
||||
tlscert->elements[XMPP_CERT_PUBKEY_FINGERPRINT_SHA256] =
|
||||
_get_fingerprint(ctx, cert, XMPP_CERT_PUBKEY_FINGERPRINT_SHA256);
|
||||
|
||||
strophe_snprintf(buf, sizeof(buf), "%ld", X509_get_version(cert) + 1);
|
||||
tlscert->elements[XMPP_CERT_VERSION] = strophe_strdup(ctx, buf);
|
||||
|
||||
23
strophe.h
23
strophe.h
@@ -251,17 +251,18 @@ typedef enum {
|
||||
* @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_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_PUBKEY_FINGERPRINT_SHA256, /**< SHA-256 fingerprint of pubkey */
|
||||
XMPP_CERT_ELEMENT_MAX /**< Last element of the enum */
|
||||
} xmpp_cert_element_t;
|
||||
|
||||
typedef struct {
|
||||
|
||||
Reference in New Issue
Block a user