On 18/09/2025 01.21, 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         | 109 ++++++++++++++++++++++++++++++++++++
  include/crypto/x509-utils.h |  39 +++++++++++++
  2 files changed, 148 insertions(+)

diff --git a/crypto/x509-utils.c b/crypto/x509-utils.c
index 763eccb190..8f3c895d7c 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,
@@ -342,6 +343,97 @@ int qcrypto_x509_is_ecc_curve_p521(uint8_t *cert, size_t 
size, Error **errp)
      return 0;
  }
+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 = {.data = NULL, .size = 0};
+
+    rc = gnutls_pkcs7_init(&signature);
+    if (rc < 0) {
+        error_setg(errp, "Failed to initalize pkcs7 data: %s", 
gnutls_strerror(rc));
+        return ret;
+     }

Indentation of the "}" is off by one.

+    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));
+        goto cleanup;
+    }
+
+    *result = g_new0(uint8_t, sig_datum_pem.size);
+    *resultlen = sig_datum_pem.size;
+    memcpy(*result, sig_datum_pem.data, sig_datum_pem.size);

I think you could replace the g_new0 + memcpy with a g_memdup2() here.

+    ret = 0;
+
+cleanup:
+    gnutls_pkcs7_deinit(signature);
+    gnutls_free(sig_datum_pem.data);
+    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));
+        goto cleanup;

So if you go to cleanup here, signature is still NULL ...

+    }
+
+    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));
+        goto cleanup;
+    }
+
+    rc = gnutls_pkcs7_init(&signature);
+    if (rc < 0) {
+        error_setg(errp, "Failed to initalize pkcs7 data: %s", 
gnutls_strerror(rc));
+        goto cleanup;
+     }
+
+    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);

... did you check whether gnutls_pkcs7_deinit() is able to deal with NULL pointers? The man-page does not mention it ... so just to be on the save side, maybe it would be better to have to cleanup labels, and only do the gnutls_pkcs7_deinit() if it has been initialized before?

+    return ret;
+}

 Thomas


Reply via email to