Show a patch.

GET /api/1.1/patches/17034/?format=api
HTTP 200 OK
Allow: GET, PUT, PATCH, HEAD, OPTIONS
Content-Type: application/json
Vary: Accept

{
    "id": 17034,
    "url": "https://patchwork.libcamera.org/api/1.1/patches/17034/?format=api",
    "web_url": "https://patchwork.libcamera.org/patch/17034/",
    "project": {
        "id": 1,
        "url": "https://patchwork.libcamera.org/api/1.1/projects/1/?format=api",
        "name": "libcamera",
        "link_name": "libcamera",
        "list_id": "libcamera_core",
        "list_email": "libcamera-devel@lists.libcamera.org",
        "web_url": "",
        "scm_url": "",
        "webscm_url": ""
    },
    "msgid": "<20220808230833.16275-4-laurent.pinchart@ideasonboard.com>",
    "date": "2022-08-08T23:08:32",
    "name": "[libcamera-devel,v2,3/4] libcamera: pub_key: Support openssl as an alternative to gnutls",
    "commit_ref": null,
    "pull_url": null,
    "state": "accepted",
    "archived": false,
    "hash": "66157cd759cf7a5e753ce5cb65bc52720245edf9",
    "submitter": {
        "id": 2,
        "url": "https://patchwork.libcamera.org/api/1.1/people/2/?format=api",
        "name": "Laurent Pinchart",
        "email": "laurent.pinchart@ideasonboard.com"
    },
    "delegate": null,
    "mbox": "https://patchwork.libcamera.org/patch/17034/mbox/",
    "series": [
        {
            "id": 3392,
            "url": "https://patchwork.libcamera.org/api/1.1/series/3392/?format=api",
            "web_url": "https://patchwork.libcamera.org/project/libcamera/list/?series=3392",
            "date": "2022-08-08T23:08:29",
            "name": "libcamera: Support openssl as an alternative to gnutls",
            "version": 2,
            "mbox": "https://patchwork.libcamera.org/series/3392/mbox/"
        }
    ],
    "comments": "https://patchwork.libcamera.org/api/patches/17034/comments/",
    "check": "pending",
    "checks": "https://patchwork.libcamera.org/api/patches/17034/checks/",
    "tags": {},
    "headers": {
        "Return-Path": "<libcamera-devel-bounces@lists.libcamera.org>",
        "X-Original-To": "parsemail@patchwork.libcamera.org",
        "Delivered-To": "parsemail@patchwork.libcamera.org",
        "Received": [
            "from lancelot.ideasonboard.com (lancelot.ideasonboard.com\n\t[92.243.16.209])\n\tby patchwork.libcamera.org (Postfix) with ESMTPS id 0478FC3272\n\tfor <parsemail@patchwork.libcamera.org>;\n\tMon,  8 Aug 2022 23:08:50 +0000 (UTC)",
            "from lancelot.ideasonboard.com (localhost [IPv6:::1])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTP id 8A7A863332;\n\tTue,  9 Aug 2022 01:08:49 +0200 (CEST)",
            "from perceval.ideasonboard.com (perceval.ideasonboard.com\n\t[IPv6:2001:4b98:dc2:55:216:3eff:fef7:d647])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTPS id 0B55A6332A\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tTue,  9 Aug 2022 01:08:48 +0200 (CEST)",
            "from pendragon.ideasonboard.com (62-78-145-57.bb.dnainternet.fi\n\t[62.78.145.57])\n\tby perceval.ideasonboard.com (Postfix) with ESMTPSA id 96C5273E;\n\tTue,  9 Aug 2022 01:08:47 +0200 (CEST)"
        ],
        "DKIM-Signature": [
            "v=1; a=rsa-sha256; c=relaxed/simple; d=libcamera.org;\n\ts=mail; t=1660000129;\n\tbh=esSq5v0LGM77PEc6KrP1DoQbZGb2PDMIzBVo+hxUrvc=;\n\th=To:Date:In-Reply-To:References:Subject:List-Id:List-Unsubscribe:\n\tList-Archive:List-Post:List-Help:List-Subscribe:From:Reply-To:\n\tFrom;\n\tb=kWSElzr9CFzkQgQzTa8Pdm+DjJqXDnudFQxW4k5/lwpXIf6yVO66jcVbKZcs3+QqQ\n\tPPmiyavkt3gww0SH7sFsJ0Zd15NVPu6/++I7jZMHVLBc7KZN+feEcOzkVYrJvhojh4\n\tcgmSM7/L1l8aMFtCWTpQWUCA7gFEmgcTcCfnEod05Ie+Y8GFGaDbncoB4r/rd8nb8k\n\tAehDCJu1gX/Tec1fTT4r7orfDwctedG0cEmn6To7oXrC8pIt5jksSegTGwCTcizS7e\n\t4pd44g6UI2DVXNVTheH7YvFYMgnUBG5uoVJ3t3DTuosILXa4323qJoDor3tAukEQuS\n\t+aSiCC7d0wsxA==",
            "v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com;\n\ts=mail; t=1660000127;\n\tbh=esSq5v0LGM77PEc6KrP1DoQbZGb2PDMIzBVo+hxUrvc=;\n\th=From:To:Cc:Subject:Date:In-Reply-To:References:From;\n\tb=jr2U574nzIuckM0MsWXB/BWjNBIxJlgsZ/1J5BaYGn6BG8yoXlAblvcbHSTVfGNHP\n\t1mRR5cuiGV+/XqkrgVveHb443sCoXX6wqXLdD3ucxBlD3dgt8/ROUJcusxNp2lADQL\n\t1Fvw/gXfZbo+95CPowwCewguAX/V+a4/ee/DsKBU="
        ],
        "Authentication-Results": "lancelot.ideasonboard.com; dkim=pass (1024-bit key; \n\tunprotected) header.d=ideasonboard.com\n\theader.i=@ideasonboard.com\n\theader.b=\"jr2U574n\"; dkim-atps=neutral",
        "To": "libcamera-devel@lists.libcamera.org",
        "Date": "Tue,  9 Aug 2022 02:08:32 +0300",
        "Message-Id": "<20220808230833.16275-4-laurent.pinchart@ideasonboard.com>",
        "X-Mailer": "git-send-email 2.35.1",
        "In-Reply-To": "<20220808230833.16275-1-laurent.pinchart@ideasonboard.com>",
        "References": "<20220808230833.16275-1-laurent.pinchart@ideasonboard.com>",
        "MIME-Version": "1.0",
        "Content-Transfer-Encoding": "8bit",
        "Subject": "[libcamera-devel] [PATCH v2 3/4] libcamera: pub_key: Support\n\topenssl as an alternative to gnutls",
        "X-BeenThere": "libcamera-devel@lists.libcamera.org",
        "X-Mailman-Version": "2.1.29",
        "Precedence": "list",
        "List-Id": "<libcamera-devel.lists.libcamera.org>",
        "List-Unsubscribe": "<https://lists.libcamera.org/options/libcamera-devel>,\n\t<mailto:libcamera-devel-request@lists.libcamera.org?subject=unsubscribe>",
        "List-Archive": "<https://lists.libcamera.org/pipermail/libcamera-devel/>",
        "List-Post": "<mailto:libcamera-devel@lists.libcamera.org>",
        "List-Help": "<mailto:libcamera-devel-request@lists.libcamera.org?subject=help>",
        "List-Subscribe": "<https://lists.libcamera.org/listinfo/libcamera-devel>,\n\t<mailto:libcamera-devel-request@lists.libcamera.org?subject=subscribe>",
        "From": "Laurent Pinchart via libcamera-devel\n\t<libcamera-devel@lists.libcamera.org>",
        "Reply-To": "Laurent Pinchart <laurent.pinchart@ideasonboard.com>",
        "Errors-To": "libcamera-devel-bounces@lists.libcamera.org",
        "Sender": "\"libcamera-devel\" <libcamera-devel-bounces@lists.libcamera.org>"
    },
    "content": "Support verify IPA signatures with openssl as an alternative to gnutls,\nto offer more flexibility in the selection of dependencies. Use gnutls\nby default, for no specific reason as both are equally well supported.\n\nSigned-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>\n---\nChanges since v1:\n\n- Don't use functions deprecated in OpenSSL 3.0\n---\n README.rst                           |  2 +-\n include/libcamera/internal/pub_key.h |  8 +++--\n src/libcamera/meson.build            | 10 ++++--\n src/libcamera/pub_key.cpp            | 47 +++++++++++++++++++++++++---\n 4 files changed, 57 insertions(+), 10 deletions(-)",
    "diff": "diff --git a/README.rst b/README.rst\nindex 77374c6a72b1..3bf4685b0e15 100644\n--- a/README.rst\n+++ b/README.rst\n@@ -61,7 +61,7 @@ for the libcamera core: [required]\n         libyaml-dev python3-yaml python3-ply python3-jinja2\n \n for IPA module signing: [required]\n-        libgnutls28-dev openssl\n+        Either libgnutls28-dev or libssl-dev, openssl\n \n for improved debugging: [optional]\n         libdw-dev libunwind-dev\ndiff --git a/include/libcamera/internal/pub_key.h b/include/libcamera/internal/pub_key.h\nindex a22ba037cff6..8653a912b2d5 100644\n--- a/include/libcamera/internal/pub_key.h\n+++ b/include/libcamera/internal/pub_key.h\n@@ -11,7 +11,9 @@\n \n #include <libcamera/base/span.h>\n \n-#if HAVE_GNUTLS\n+#if HAVE_CRYPTO\n+struct evp_pkey_st;\n+#elif HAVE_GNUTLS\n struct gnutls_pubkey_st;\n #endif\n \n@@ -28,7 +30,9 @@ public:\n \n private:\n \tbool valid_;\n-#if HAVE_GNUTLS\n+#if HAVE_CRYPTO\n+\tstruct evp_pkey_st *pubkey_;\n+#elif HAVE_GNUTLS\n \tstruct gnutls_pubkey_st *pubkey_;\n #endif\n };\ndiff --git a/src/libcamera/meson.build b/src/libcamera/meson.build\nindex 7cc06de4aedc..401fc498cfbc 100644\n--- a/src/libcamera/meson.build\n+++ b/src/libcamera/meson.build\n@@ -65,12 +65,16 @@ subdir('pipeline')\n subdir('proxy')\n \n libdl = cc.find_library('dl')\n-libgnutls = dependency('gnutls', required : true)\n libudev = dependency('libudev', required : false)\n libyaml = dependency('yaml-0.1', required : false)\n \n-if libgnutls.found()\n+# Use one of gnutls or libcrypto (provided by OpenSSL), trying gnutls first.\n+libcrypto = dependency('gnutls2', required : false)\n+if libcrypto.found()\n     config_h.set('HAVE_GNUTLS', 1)\n+else\n+    libcrypto = dependency('libcrypto', required : true)\n+    config_h.set('HAVE_CRYPTO', 1)\n endif\n \n if liblttng.found()\n@@ -135,8 +139,8 @@ libcamera_deps = [\n     libatomic,\n     libcamera_base,\n     libcamera_base_private,\n+    libcrypto,\n     libdl,\n-    libgnutls,\n     liblttng,\n     libudev,\n     libyaml,\ndiff --git a/src/libcamera/pub_key.cpp b/src/libcamera/pub_key.cpp\nindex b2045a103bc0..64dfa23497c2 100644\n--- a/src/libcamera/pub_key.cpp\n+++ b/src/libcamera/pub_key.cpp\n@@ -7,7 +7,12 @@\n \n #include \"libcamera/internal/pub_key.h\"\n \n-#if HAVE_GNUTLS\n+#if HAVE_CRYPTO\n+#include <openssl/evp.h>\n+#include <openssl/rsa.h>\n+#include <openssl/sha.h>\n+#include <openssl/x509.h>\n+#elif HAVE_GNUTLS\n #include <gnutls/abstract.h>\n #endif\n \n@@ -33,7 +38,14 @@ namespace libcamera {\n PubKey::PubKey([[maybe_unused]] Span<const uint8_t> key)\n \t: valid_(false)\n {\n-#if HAVE_GNUTLS\n+#if HAVE_CRYPTO\n+\tconst uint8_t *data = key.data();\n+\tpubkey_ = d2i_PUBKEY(nullptr, &data, key.size());\n+\tif (!pubkey_)\n+\t\treturn;\n+\n+\tvalid_ = true;\n+#elif HAVE_GNUTLS\n \tint ret = gnutls_pubkey_init(&pubkey_);\n \tif (ret < 0)\n \t\treturn;\n@@ -52,7 +64,9 @@ PubKey::PubKey([[maybe_unused]] Span<const uint8_t> key)\n \n PubKey::~PubKey()\n {\n-#if HAVE_GNUTLS\n+#if HAVE_CRYPTO\n+\tEVP_PKEY_free(pubkey_);\n+#elif HAVE_GNUTLS\n \tgnutls_pubkey_deinit(pubkey_);\n #endif\n }\n@@ -79,7 +93,32 @@ bool PubKey::verify([[maybe_unused]] Span<const uint8_t> data,\n \tif (!valid_)\n \t\treturn false;\n \n-#if HAVE_GNUTLS\n+#if HAVE_CRYPTO\n+\t/*\n+\t * Create and initialize a public key algorithm context for signature\n+\t * verification.\n+\t */\n+\tEVP_PKEY_CTX *ctx = EVP_PKEY_CTX_new(pubkey_, nullptr);\n+\tif (!ctx)\n+\t\treturn false;\n+\n+\tif (EVP_PKEY_verify_init(ctx) <= 0 ||\n+\t    EVP_PKEY_CTX_set_rsa_padding(ctx, RSA_PKCS1_PADDING) <= 0 ||\n+\t    EVP_PKEY_CTX_set_signature_md(ctx, EVP_sha256()) <= 0) {\n+\t\tEVP_PKEY_CTX_free(ctx);\n+\t\treturn false;\n+\t}\n+\n+\t/* Calculate the SHA256 digest of the data. */\n+\tuint8_t digest[SHA256_DIGEST_LENGTH];\n+\tSHA256(data.data(), data.size(), digest);\n+\n+\t/* Decrypt the signature and verify it matches the digest. */\n+\tint ret = EVP_PKEY_verify(ctx, sig.data(), sig.size(), digest,\n+\t\t\t\t  SHA256_DIGEST_LENGTH);\n+\tEVP_PKEY_CTX_free(ctx);\n+\treturn ret == 1;\n+#elif HAVE_GNUTLS\n \tconst gnutls_datum_t gnuTlsData{\n \t\tconst_cast<unsigned char *>(data.data()),\n \t\tstatic_cast<unsigned int>(data.size())\n",
    "prefixes": [
        "libcamera-devel",
        "v2",
        "3/4"
    ]
}