diff options
| author | Zhuoying Cai <zycai@linux.ibm.com> | 2026-07-30 17:46:01 -0400 |
|---|---|---|
| committer | Eric Farman <farman@linux.ibm.com> | 2026-08-26 06:52:20 -0400 |
| commit | ea691e20cc9b270b9edafd27fc7dea09fcd1f541 (patch) | |
| tree | ac97c9b9c12688a9a733f6e48cc9be8e4806990b /crypto | |
| parent | 06b8b50b057a08ed3680599866b69240dc006034 (diff) | |
| download | qemu-ea691e20cc9b270b9edafd27fc7dea09fcd1f541.tar.gz qemu-ea691e20cc9b270b9edafd27fc7dea09fcd1f541.zip | |
crypto/x509-utils: Add helper functions for DIAG 508 subcode 1
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 <zycai@linux.ibm.com>
Acked-by: Daniel P. Berrangé <berrange@redhat.com>
Reviewed-by: Daniel P. Berrangé <berrange@redhat.com>
Reviewed-by: Farhan Ali <alifm@linux.ibm.com>
Reviewed-by: Thomas Huth <thuth@redhat.com>
Link: https://lore.kernel.org/qemu-devel/20260730214624.2328883-13-zycai@linux.ibm.com
Signed-off-by: Eric Farman <farman@linux.ibm.com>
Diffstat (limited to 'crypto')
| -rw-r--r-- | crypto/x509-utils.c | 108 |
1 files changed, 108 insertions, 0 deletions
diff --git a/crypto/x509-utils.c b/crypto/x509-utils.c index 543fc3007d..e4767f9838 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, @@ -336,6 +337,96 @@ int qcrypto_x509_check_ecc_curve_p521(uint8_t *cert, size_t size, Error **errp) return curve_id == GNUTLS_ECC_CURVE_SECP521R1; } +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 initialize 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)); + goto cleanup; + } + + *resultlen = sig_datum_pem.size; + *result = g_memdup2(sig_datum_pem.data, sig_datum_pem.size); + + ret = 0; + +cleanup: + gnutls_pkcs7_deinit(signature); + g_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; + } + + 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 initialize 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); + return ret; +} + #else /* ! CONFIG_GNUTLS */ int qcrypto_get_x509_cert_fingerprint(uint8_t *cert, size_t size, @@ -379,4 +470,21 @@ int qcrypto_x509_check_ecc_curve_p521(uint8_t *cert, size_t size, Error **errp) return -1; } +int qcrypto_pkcs7_convert_sig_pem(uint8_t *sig, size_t sig_size, + uint8_t **result, + size_t *resultlen, + Error **errp) +{ + error_setg(errp, "GNUTLS is required to export pkcs7 signature"); + return -1; +} + +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) +{ + error_setg(errp, "GNUTLS is required for signature-verification support"); + return -1; +} + #endif /* ! CONFIG_GNUTLS */ |
