Add helper functions for x509 certificate which will be used in the next patch for DIAG 508 subcode 1.
Signed-off-by: Zhuoying Cai <[email protected]> --- crypto/x509-utils.c | 61 +++++++++++++++++++++++++++++++++++++ include/crypto/x509-utils.h | 20 ++++++++++++ 2 files changed, 81 insertions(+) diff --git a/crypto/x509-utils.c b/crypto/x509-utils.c index dd8137210c..4c997cf5d4 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, @@ -364,6 +365,58 @@ cleanup: return ret; } +static int qcrypto_import_pkcs7(gnutls_pkcs7_t pkcs7, gnutls_datum_t *datum) +{ + int rc; + + rc = gnutls_pkcs7_import(pkcs7, datum , GNUTLS_X509_FMT_PEM); + if (rc) { + rc = gnutls_pkcs7_import(pkcs7, datum , GNUTLS_X509_FMT_DER); + } + + return rc; +} + +int qcrypto_verify_x509_cert(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 = -1; + gnutls_x509_crt_t crt; + gnutls_pkcs7_t signature; + 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}; + + if (gnutls_x509_crt_init(&crt) < 0) { + error_setg(errp, "Failed to initialize certificate"); + return rc; + } + + if (qcrypto_import_x509_cert(crt, &cert_datum) != 0) { + error_setg(errp, "Failed to import certificate"); + gnutls_x509_crt_deinit(crt); + return rc; + } + + if (gnutls_pkcs7_init(&signature) < 0) { + error_setg(errp, "Failed to initalize pkcs7 data."); + return rc; + } + + if (qcrypto_import_pkcs7(signature, &sig_datum) != 0) { + error_setg(errp, "Failed to import signature"); + goto cleanup; + } + + rc = gnutls_pkcs7_verify_direct(signature, crt, 0, &data_datum, 0); + +cleanup: + gnutls_x509_crt_deinit(crt); + gnutls_pkcs7_deinit(signature); + return rc; +} + #else /* ! CONFIG_GNUTLS */ int qcrypto_check_x509_cert_fmt(uint8_t *cert, size_t size, @@ -427,4 +480,12 @@ int qcrypto_get_x509_cert_key_id(uint8_t *cert, size_t size, return -ENOTSUP; } +int qcrypto_verify_x509_cert(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 -ENOTSUP; +} + #endif /* ! CONFIG_GNUTLS */ diff --git a/include/crypto/x509-utils.h b/include/crypto/x509-utils.h index 4a9941b33d..0b698b1b08 100644 --- a/include/crypto/x509-utils.h +++ b/include/crypto/x509-utils.h @@ -136,4 +136,24 @@ int qcrypto_get_x509_cert_key_id(uint8_t *cert, size_t size, size_t *resultlen, Error **errp); +/** + * qcrypto_verify_x509_cert + * @cert: pointer to the raw certiricate data + * @cert_size: size of the certificate + * @comp: pointer to the component to be verified + * @comp_size: size of the component + * @sig: pointer to the signature + * @sig_size: size of the signature + * @errp: error pointer + * + * Verify the provided @comp against the @sig and @cert. + * + * Returns: 0 on success, + * negative error code on error, + * -ENOTSUP if GNUTLS is not enabled. + */ +int qcrypto_verify_x509_cert(uint8_t *cert, size_t cert_size, + uint8_t *comp, size_t comp_size, + uint8_t *sig, size_t sig_size, Error **errp); + #endif -- 2.49.0
