diff --git a/include/libwebsockets/lws-x509.h b/include/libwebsockets/lws-x509.h index 03656c5b7..55b660093 100644 --- a/include/libwebsockets/lws-x509.h +++ b/include/libwebsockets/lws-x509.h @@ -42,6 +42,11 @@ enum lws_tls_cert_info { * same tls backend, ie, OpenSSL or mbedTLS. The different backends * produce different, incompatible representations for the same cert. */ + LWS_TLS_CERT_INFO_DER_RAW, + /**< the certificate's raw DER representation. If it's too big, + * -1 is returned and the size will be returned in buf->ns.len. + * If the certificate cannot be found -1 is returned and 0 in + * buf->ns.len. */ }; union lws_tls_cert_info_results { diff --git a/lib/tls/mbedtls/mbedtls-x509.c b/lib/tls/mbedtls/mbedtls-x509.c index 523d55386..cead97550 100644 --- a/lib/tls/mbedtls/mbedtls-x509.c +++ b/lib/tls/mbedtls/mbedtls-x509.c @@ -166,6 +166,19 @@ lws_tls_mbedtls_cert_info(mbedtls_x509_crt *x509, enum lws_tls_cert_info type, } break; } + case LWS_TLS_CERT_INFO_DER_RAW: + + buf->ns.len = (int)x509->raw.len; + + if (len < x509->raw.len) + /* + * The buffer is too small and the attempt failed, but + * the required object length is in buf->ns.len + */ + return -1; + + memcpy(buf->ns.name, x509->raw.p, x509->raw.len); + break; default: return -1; diff --git a/lib/tls/openssl/openssl-x509.c b/lib/tls/openssl/openssl-x509.c index c33c7839a..6ba59b2b9 100644 --- a/lib/tls/openssl/openssl-x509.c +++ b/lib/tls/openssl/openssl-x509.c @@ -164,6 +164,22 @@ lws_tls_openssl_cert_info(X509 *x509, enum lws_tls_cert_info type, #endif return 0; } + case LWS_TLS_CERT_INFO_DER_RAW: + { + int der_len = i2d_X509(x509, NULL); + uint8_t *tmp = (uint8_t *)buf->ns.name; + + buf->ns.len = der_len < 0 ? 0 : der_len; + + if (der_len < 0 || (size_t)der_len > len) + return -1; + + der_len = i2d_X509(x509, &tmp); + if (der_len < 0) + return -1; + + return 0; + } default: return -1; }