On Fri, Jul 11, 2025 at 05:10:47PM -0400, Zhuoying Cai wrote:
> Introduce helper functions to support signature verification required by
> DIAG 508 subcode 1:
>
> qcrypto_pkcs7_convert_sig_pem() – converts a signature from DER to PEM format
> qcrypto_x509_verify_sig() – verifies the provided data against the given
> signature
>
> These functions enable basic signature verification support.
>
> Signed-off-by: Zhuoying Cai <[email protected]>
> ---
> crypto/x509-utils.c | 110 ++++++++++++++++++++++++++++++++++++
> include/crypto/x509-utils.h | 39 +++++++++++++
> 2 files changed, 149 insertions(+)
>
> diff --git a/crypto/x509-utils.c b/crypto/x509-utils.c
> index 135f83f55e..2b1ed5ee26 100644
> --- a/crypto/x509-utils.c
> +++ b/crypto/x509-utils.c
> @@ -16,6 +16,7 @@
> #include <gnutls/gnutls.h>
> #include <gnutls/crypto.h>
> #include <gnutls/x509.h>
> +#include <gnutls/pkcs7.h>
>
> static const int qcrypto_to_gnutls_hash_alg_map[QCRYPTO_HASH_ALGO__MAX] = {
> [QCRYPTO_HASH_ALGO_MD5] = GNUTLS_DIG_MD5,
> @@ -366,6 +367,98 @@ cleanup:
> return ret;
> }
>
> +int qcrypto_pkcs7_convert_sig_pem(uint8_t *sig, size_t sig_size,
> + uint8_t **result, size_t *resultlen,
> + Error **errp)
> +{
> + int ret = -1;
> + int rc;
> + gnutls_pkcs7_t signature;
> + gnutls_datum_t sig_datum_der = {.data = sig, .size = sig_size};
> + gnutls_datum_t sig_datum_pem = { 0, };
> +
> + rc = gnutls_pkcs7_init(&signature);
> + if (rc < 0) {
> + error_setg(errp, "Failed to initalize pkcs7 data: %s",
> gnutls_strerror(rc));
> + return ret;
> + }
> +
> + rc = gnutls_pkcs7_import(signature, &sig_datum_der, GNUTLS_X509_FMT_DER);
> + if (rc != 0) {
> + error_setg(errp, "Failed to import signature: %s",
> gnutls_strerror(rc));
> + goto cleanup;
> + }
> +
> + rc = gnutls_pkcs7_export2(signature, GNUTLS_X509_FMT_PEM,
> &sig_datum_pem);
> + if (rc != 0) {
> + error_setg(errp, "Failed to convert signature to PEM format: %s",
> + gnutls_strerror(rc));
> + gnutls_free(sig_datum_pem.data);
> + goto cleanup;
> + }
> +
> + *result = g_steal_pointer(&sig_datum_pem.data);
> + *resultlen = sig_datum_pem.size;
> +
> + ret = 0;
> +
> +cleanup:
> + gnutls_pkcs7_deinit(signature);
> + return ret;
> +}
> +
> +int qcrypto_x509_verify_sig(uint8_t *cert, size_t cert_size,
> + uint8_t *comp, size_t comp_size,
> + uint8_t *sig, size_t sig_size, Error **errp)
> +{
> + int rc;
> + int ret = -1;
> + gnutls_x509_crt_t crt;
= NULL;
> + gnutls_pkcs7_t signature;
= NULL;
> + gnutls_datum_t cert_datum = {.data = cert, .size = cert_size};
> + gnutls_datum_t data_datum = {.data = comp, .size = comp_size};
> + gnutls_datum_t sig_datum = {.data = sig, .size = sig_size};
> +
> + rc = gnutls_x509_crt_init(&crt);
> + if (rc < 0) {
> + error_setg(errp, "Failed to initialize certificate: %s",
> gnutls_strerror(rc));
> + return ret;
goto cleanup;
> + }
> +
> + rc = gnutls_x509_crt_import(crt, &cert_datum, GNUTLS_X509_FMT_PEM);
> + if (rc != 0) {
> + error_setg(errp, "Failed to import certificate: %s",
> gnutls_strerror(rc));
> + gnutls_x509_crt_deinit(crt);
Drop this
> + return ret;
goto cleanup;
> + }
> +
> + rc = gnutls_pkcs7_init(&signature);
> + if (rc < 0) {
> + error_setg(errp, "Failed to initalize pkcs7 data: %s",
> gnutls_strerror(rc));
> + gnutls_x509_crt_deinit(crt);
> + return ret;
Likewise
> + }
> +
> + rc = gnutls_pkcs7_import(signature, &sig_datum , GNUTLS_X509_FMT_PEM);
> + if (rc != 0) {
> + error_setg(errp, "Failed to import signature: %s",
> gnutls_strerror(rc));
> + goto cleanup;
> + }
> +
> + rc = gnutls_pkcs7_verify_direct(signature, crt, 0, &data_datum, 0);
> + if (rc != 0) {
> + error_setg(errp, "Failed to verify signature: %s",
> gnutls_strerror(rc));
> + goto cleanup;
> + }
> +
> + ret = 0;
> +
> +cleanup:
> + gnutls_x509_crt_deinit(crt);
> + gnutls_pkcs7_deinit(signature);
Both of these are safe to call with NULL, hence we can add the
"goto cleanup" mentioned above.
> + return ret;
> +}
With regards,
Daniel
--
|: https://berrange.com -o- https://www.flickr.com/photos/dberrange :|
|: https://libvirt.org -o- https://fstop138.berrange.com :|
|: https://entangle-photo.org -o- https://www.instagram.com/dberrange :|