From patchwork Wed Jul 22 15:25:14 2026 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Gert Doering X-Patchwork-Id: 5120 Return-Path: Delivered-To: patchwork@openvpn.net Received: by 2002:a05:7001:a3d1:10b0:87d:a30e:ad06 with SMTP id wz17-n1csp335230mab; Wed, 22 Jul 2026 08:25:37 -0700 (PDT) X-Forwarded-Encrypted: i=2; AHgh+RpVdM6VDdBXxWZpXPPxtOw6qrwj4VQ3onT77axF6Mz0LK9DdKuHRDXczKWW44l5szOUeM7wh+dCuGY=@openvpn.net X-Received: by 2002:a05:6830:2404:b0:7e6:ef2e:28a5 with SMTP id 46e09a7af769-7eda4d39a64mr12749155a34.15.1784733936889; Wed, 22 Jul 2026 08:25:36 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1784733936; cv=none; d=google.com; s=arc-20260327; b=I2oSF5l4X4b3vGj067Df52p14CaUKXqAMT8fowyX7X7h/Ysw11/fsSO42mdyCD4sN7 6YDzWqzuQPrazhYKYB+dZTddhToy6odqPn/qiLU2V6VxjxPw++JhAnVwUJOS994MASJD /X3wf2OwLSpPgclyJ2mVUvD+vG8JX+1isNOXSu4lyuYvMIaf5Fqp7GMJW1CQFE7T3233 GnE6n0uPw44yaWejwH2cBhqAvtLCJ7BCpdxIHfXUy6nAI68H2hN04BOcP4cjHG+BoR0P DLgatFNJReq8kktcLiioz0LMWDZsksv9hYkauPgY11VxnYfnGxKnFK+XXU828MXnUMog 5+Zg== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20260327; h=errors-to:content-transfer-encoding:list-subscribe:list-help :list-post:list-archive:list-unsubscribe:list-id:precedence:subject :mime-version:references:in-reply-to:message-id:date:to:from :dkim-signature:dkim-signature:dkim-signature; bh=C8g3kP76WnfL8sG0QZ3yI5K/8ww9VZ8Ps9AcsLHG7KI=; fh=4NbAC/LsuMLI0S0hprUlLSLCiHwg6SCAifhH718Jh0Q=; b=PDW7TLZF+kK7Kysu3yGJA/YjZoRz9cKPXNx4h3FFyYWzNY7tAuNB3zDACnLuHzH6Ci RiMj+IC9gaDQoVuP6ne70qw4R1rhIya138nC+AS2TXwsmzjTABCsfmPVgWlDkf0DkzWh uBVVJOdsHx7bOl4qYb2MC+hbqrQ1/dO6J3m/4bwantDg4ZyIRkdi0MZrPKEEW5JZJYAa WKH3M3O3PpX9npwOVa08NGwQ/Cwu7ZJfPGLo2Jpk6agUF0IKQ4LBX+ETLxlKTVq9p9Mp ijgfbTAENZh2XcvlCao3dKHo64PTBtuz8xlmZWvJI+WuP0ixvcjM2RxvJTilSl184YXL 8BFA==; dara=google.com ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@lists.sourceforge.net header.s=beta header.b=ZCz2vl5n; dkim=neutral (body hash did not verify) header.i=@sourceforge.net header.s=x header.b=fudpKA0q; dkim=neutral (body hash did not verify) header.i=@sf.net header.s=x header.b=Cgzb8XTN; spf=pass (google.com: domain of openvpn-devel-bounces@lists.sourceforge.net designates 216.105.38.7 as permitted sender) smtp.mailfrom=openvpn-devel-bounces@lists.sourceforge.net; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=muc.de Received: from lists.sourceforge.net (lists.sourceforge.net. [216.105.38.7]) by mx.google.com with ESMTPS id 46e09a7af769-7ee2a0b4a51si1412871a34.96.2026.07.22.08.25.36 (version=TLS1_2 cipher=ECDHE-ECDSA-AES128-GCM-SHA256 bits=128/128); Wed, 22 Jul 2026 08:25:36 -0700 (PDT) Received-SPF: pass (google.com: domain of openvpn-devel-bounces@lists.sourceforge.net designates 216.105.38.7 as permitted sender) client-ip=216.105.38.7; Authentication-Results: mx.google.com; dkim=pass header.i=@lists.sourceforge.net header.s=beta header.b=ZCz2vl5n; dkim=neutral (body hash did not verify) header.i=@sourceforge.net header.s=x header.b=fudpKA0q; dkim=neutral (body hash did not verify) header.i=@sf.net header.s=x header.b=Cgzb8XTN; spf=pass (google.com: domain of openvpn-devel-bounces@lists.sourceforge.net designates 216.105.38.7 as permitted sender) smtp.mailfrom=openvpn-devel-bounces@lists.sourceforge.net; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=muc.de DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.sourceforge.net; s=beta; h=Content-Transfer-Encoding:Content-Type: List-Subscribe:List-Help:List-Post:List-Archive:List-Unsubscribe:List-Id: Subject:MIME-Version:References:In-Reply-To:Message-ID:Date:To:From:Sender: Reply-To:Cc:Content-ID:Content-Description:Resent-Date:Resent-From: Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID:List-Owner; bh=C8g3kP76WnfL8sG0QZ3yI5K/8ww9VZ8Ps9AcsLHG7KI=; b=ZCz2vl5n0ltAn4rkg3ALbjh1kU 9LXE/9PjDV087ppzwd9HpgXYt6GwskYu/oj9hjCYXPS9uvPCQ2nzmqLNI2xNZX7sJH50/FPQgUUb8 rKF/d1aWJRFDB/CZ1ZrRgvttrVA4New4+s78FNgysL3Y+dsG01u3Rvf9CaSZ29AqxxiQ=; Received: from [127.0.0.1] (helo=sfs-ml-3.v29.lw.sourceforge.com) by sfs-ml-3.v29.lw.sourceforge.com with esmtp (Exim 4.95) (envelope-from ) id 1wmYp9-0005qP-SQ; Wed, 22 Jul 2026 15:25:32 +0000 Received: from [172.30.29.66] (helo=mx.sourceforge.net) by sfs-ml-3.v29.lw.sourceforge.com with esmtps (TLS1.2) tls TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (Exim 4.95) (envelope-from ) id 1wmYp8-0005qI-3b for openvpn-devel@lists.sourceforge.net; Wed, 22 Jul 2026 15:25:30 +0000 DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=sourceforge.net; s=x; h=Content-Transfer-Encoding:Content-Type:MIME-Version :References:In-Reply-To:Message-ID:Date:Subject:To:From:Sender:Reply-To:Cc: Content-ID:Content-Description:Resent-Date:Resent-From:Resent-Sender: Resent-To:Resent-Cc:Resent-Message-ID:List-Id:List-Help:List-Unsubscribe: List-Subscribe:List-Post:List-Owner:List-Archive; bh=gJxhUPfWkkih53vT2+8iS2cnNHMsqj3Xl6lyzxZWHC8=; b=fudpKA0qZlVEiiHFKHl7DHku6C 21qJYOT6Xiv4GVM8bUH1vAfj17Sv443e1+++IM2zMP+rf8pQM+3n/kCgfTOH8aorRu4n0k00hKahU 7GK/8WdwrygjH6Aq4/xUjAxEpfZ03NypTZ3gLRvqQ7xjSJML0H4KkYH9tMWV/dk+b81M=; DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=sf.net; s=x ; h=Content-Transfer-Encoding:Content-Type:MIME-Version:References: In-Reply-To:Message-ID:Date:Subject:To:From:Sender:Reply-To:Cc:Content-ID: Content-Description:Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc :Resent-Message-ID:List-Id:List-Help:List-Unsubscribe:List-Subscribe: List-Post:List-Owner:List-Archive; bh=gJxhUPfWkkih53vT2+8iS2cnNHMsqj3Xl6lyzxZWHC8=; b=Cgzb8XTNfBXIhQwRk0f8g1ZPhy Id4htA+qhGXuHGgJwVi2SIs0m7XvyImtAVKmSWMgQw+m3VeEp2EZoS407gd5Lkv74osxII/at6aO8 iJS2Sa2z3n1J7tPke4ITpf0pC0Pnf9Ml+2P7AmVettMTcezm1r4Lwz5y5pystAiDAep8=; Received: from [193.149.48.129] (helo=blue.greenie.muc.de) by sfi-mx-2.v28.lw.sourceforge.com with esmtps (TLS1.2:ECDHE-RSA-AES256-GCM-SHA384:256) (Exim 4.95) id 1wmYp6-0004x1-PJ for openvpn-devel@lists.sourceforge.net; Wed, 22 Jul 2026 15:25:30 +0000 Received: from blue.greenie.muc.de (localhost [127.0.0.1]) by blue.greenie.muc.de (8.18.1/8.18.1) with ESMTP id 66MFPLLT022292 for ; Wed, 22 Jul 2026 17:25:21 +0200 Received: (from gert@localhost) by blue.greenie.muc.de (8.18.2/8.18.1/Submit) id 66MFPLUm022291 for openvpn-devel@lists.sourceforge.net; Wed, 22 Jul 2026 17:25:21 +0200 From: Gert Doering To: openvpn-devel@lists.sourceforge.net Date: Wed, 22 Jul 2026 17:25:14 +0200 Message-ID: <20260722152521.22272-1-gert@greenie.muc.de> X-Mailer: git-send-email 2.53.0 In-Reply-To: References: MIME-Version: 1.0 X-Spam-Score: 1.3 (+) X-Spam-Report: Spam detection software, running on the system "sfi-spamd-1.hosts.colo.sdot.me", has NOT identified this incoming email as spam. The original message has been attached to this so you can view it or label similar future email. If you have any questions, see the administrator of that system for details. Content preview: From: Max Fillinger In pre-2.7 versions, this option was not available in the Mbed TLS build. This was changed in 2.7, but the option did not do anything when Mbed TLS was selected as the crypto library. Regardless of th [...] Content analysis details: (1.3 points, 5.0 required) pts rule name description ---- ---------------------- -------------------------------------------------- 1.3 RDNS_NONE Delivered to internal network by a host with no rDNS X-Headers-End: 1wmYp6-0004x1-PJ Subject: [Openvpn-devel] [PATCH v3] Make --x509-username-field work with Mbed TLS X-BeenThere: openvpn-devel@lists.sourceforge.net X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: openvpn-devel-bounces@lists.sourceforge.net X-getmail-retrieved-from-mailbox: Inbox X-GMAIL-THRID: 1871429172772452230 X-GMAIL-MSGID: 1871429172772452230 From: Max Fillinger In pre-2.7 versions, this option was not available in the Mbed TLS build. This was changed in 2.7, but the option did not do anything when Mbed TLS was selected as the crypto library. Regardless of the field chosen with --x509-username-field, OpenVPN would always extract the CN as username. This could lead to a situation where an unintended certificate gets accepted by OpenVPN: If we run with "--x509-username-field serialNumber" and "--verify-x509-name 0x05 name", OpenVPN would accept a certificate with CN=0x05 and an incorrect serial number, while a certificate with the correct serial number would be rejected. (Though note that to exploit this, an attacker needs to make the CA sign a certificate with a hexadecimal number in the CN.) This commit adds code to backend_x509_get_username to extract the correct field values from X509 certificates. It also changes the behavior of the function to match the OpenSSL version when the output buffer is too small. (With Mbed TLS, the function would silently truncate the output and return SUCCESS.) It also adds unit tests for extracting the values of different fields. Despite this commit fixing a CVE, we have decided not to keep it under embargo until the release of the next version because it is unlikely to be exploitable in practice: Someone has to run OpenVPN 2.7 with Mbed TLS, use the --x509-username-field option even though it didn't exist in Mbed TLS builds of earlier versions, not notice that the intended certificate is *not* accepted, and then an attacker has to get the CA to sign a certificate with a weird common name. CVE: 2026-63650 Github: openvpn/openvpn-private-issues#144 Reported-By: Hcamael Reported-By: 章鱼哥 (www.aipyaipy.com) Change-Id: Ic183f1f1f90561454b7b1128c95255368427cc4a Signed-off-by: Max Fillinger Acked-by: Frank Lichtenheld Gerrit URL: https://gerrit.openvpn.net/c/openvpn/+/1801 --- This change was reviewed on Gerrit and approved by at least one developer. I request to merge it to master. Gerrit URL: https://gerrit.openvpn.net/c/openvpn/+/1801 This mail reflects revision 3 of this Change. Acked-by according to Gerrit (reflected above): Frank Lichtenheld diff --git a/src/openvpn/ssl_verify_mbedtls.c b/src/openvpn/ssl_verify_mbedtls.c index ad5479c..2a09e86 100644 --- a/src/openvpn/ssl_verify_mbedtls.c +++ b/src/openvpn/ssl_verify_mbedtls.c @@ -137,19 +137,133 @@ return false; } +static const char * +fieldname_to_oid(const char *fieldname) +{ + if (strcmp(fieldname, "C") == 0) + { + return MBEDTLS_OID_AT_COUNTRY; + } + else if (strcmp(fieldname, "ST") == 0) + { + return MBEDTLS_OID_AT_STATE; + } + else if (strcmp(fieldname, "LOCALITY") == 0) + { + return MBEDTLS_OID_AT_LOCALITY; + } + else if (strcmp(fieldname, "O") == 0) + { + return MBEDTLS_OID_AT_ORGANIZATION; + } + else if (strcmp(fieldname, "OU") == 0) + { + return MBEDTLS_OID_AT_ORG_UNIT; + } + else if (strcmp(fieldname, "CN") == 0) + { + return MBEDTLS_OID_AT_CN; + } + else if (strcmp(fieldname, "GN") == 0) + { + return MBEDTLS_OID_AT_GIVEN_NAME; + } + else if (strcmp(fieldname, "SN") == 0) + { + return MBEDTLS_OID_AT_SUR_NAME; + } + else if (strcmp(fieldname, "initials") == 0) + { + return MBEDTLS_OID_AT_INITIALS; + } + else if (strcmp(fieldname, "pseudonym") == 0) + { + return MBEDTLS_OID_AT_PSEUDONYM; + } + else if (strcmp(fieldname, "title") == 0) + { + return MBEDTLS_OID_AT_TITLE; + } + else if (strcmp(fieldname, "generationQualifier") == 0) + { + return MBEDTLS_OID_AT_GENERATION_QUALIFIER; + } + else if (strcmp(fieldname, "postalAddress") == 0) + { + return MBEDTLS_OID_AT_POSTAL_ADDRESS; + } + else if (strcmp(fieldname, "postalCode") == 0) + { + return MBEDTLS_OID_AT_POSTAL_CODE; + } + else if (strcmp(fieldname, "emailAddress") == 0) + { + return MBEDTLS_OID_PKCS9_EMAIL; + } + else if (strcmp(fieldname, "uid") == 0) + { + return MBEDTLS_OID_AT_UNIQUE_IDENTIFIER; + } + else if (strcmp(fieldname, "dnQualifier") == 0) + { + return MBEDTLS_OID_AT_DN_QUALIFIER; + } + else + { + return NULL; + } +} + result_t backend_x509_get_username(char *cn, size_t cn_len, char *x509_username_field, mbedtls_x509_crt *cert) { - mbedtls_x509_name *name; + ASSERT(cn != NULL && cn_len > 0 && cert != NULL); - ASSERT(cn != NULL); + if (x509_username_field == NULL) + { + goto fail; + } - name = &cert->subject; + if (strcmp(x509_username_field, "serialNumber") == 0) + { + if (cn_len < 2) + { + goto fail; + } + cn[0] = '0'; + cn[1] = 'x'; + size_t cn_index = 2; + bool leading_zeros = true; + for (size_t i = 0; i < cert->serial.len; i++) + { + uint8_t serial_byte = cert->serial.p[i]; + if (leading_zeros && serial_byte == 0) + { + continue; + } + leading_zeros = false; + if (cn_index > cn_len - 3) + { + goto fail; + } + snprintf(&cn[cn_index], cn_len - cn_index, "%02X", serial_byte); + cn_index += 2; + } + return SUCCESS; + } - /* Find common name */ + const char *field_oid = fieldname_to_oid(x509_username_field); + if (field_oid == NULL) + { + goto fail; + } + + /* Find field_oid in the subject name. */ + mbedtls_x509_name *name = &cert->subject; while (name != NULL) { - if (0 == memcmp(name->oid.p, MBEDTLS_OID_AT_CN, MBEDTLS_OID_SIZE(MBEDTLS_OID_AT_CN))) + if (strlen(field_oid) == name->oid.len + && 0 == memcmp(name->oid.p, field_oid, name->oid.len)) { break; } @@ -160,22 +274,23 @@ /* Not found, return an error if this is the peer's certificate */ if (name == NULL) { - return FAILURE; + goto fail; } - /* Found, extract CN */ - if (cn_len > name->val.len) + /* Check that we have room in the buffer, including the terminating '/0' byte. */ + if (cn_len <= name->val.len) { - memcpy(cn, name->val.p, name->val.len); - cn[name->val.len] = '\0'; + goto fail; } - else - { - memcpy(cn, name->val.p, cn_len); - cn[cn_len - 1] = '\0'; - } + + memcpy(cn, name->val.p, name->val.len); + cn[name->val.len] = '\0'; return SUCCESS; + +fail: + cn[0] = '\0'; + return FAILURE; } #if MBEDTLS_VERSION_NUMBER >= 0x04000000 diff --git a/tests/unit_tests/openvpn/test_ssl.c b/tests/unit_tests/openvpn/test_ssl.c index 0e9cecf..d473d67 100644 --- a/tests/unit_tests/openvpn/test_ssl.c +++ b/tests/unit_tests/openvpn/test_ssl.c @@ -775,7 +775,7 @@ static openvpn_x509_cert_t * get_certificate(const char *cert_str) { - BIO *in = BIO_new_mem_buf((char *)cert1, -1); + BIO *in = BIO_new_mem_buf((char *)cert_str, -1); assert_non_null(in); X509 *cert = PEM_read_bio_X509(in, NULL, NULL, NULL); assert_non_null(cert); @@ -790,10 +790,37 @@ } #endif +/* Generated with: + * openssl req -x509 -newkey ec -pkeyopt ec_paramgen_curve:secp384r1 -keyout - -noenc -sha256 -days 3650 \ + * -subj '/CN=ovpn-test-secp384r1/O=OpenVPN Unit Test Example Corp./OU=Cert Details Dept.' + * -addext 'subjectAltName=DNS:unittest.example.com' -addext 'extendedKeyUsage=clientAuth' */ +static const char *cert_details_test_cert = + "-----BEGIN CERTIFICATE-----\n" + "MIICkzCCAhqgAwIBAgIUKDsZM+PApGdaD2QF9iYaxoFJAkowCgYIKoZIzj0EAwIw\n" + "ZTEcMBoGA1UEAwwTb3Zwbi10ZXN0LXNlY3AzODRyMTEoMCYGA1UECgwfT3BlblZQ\n" + "TiBVbml0IFRlc3QgRXhhbXBsZSBDb3JwLjEbMBkGA1UECwwSQ2VydCBEZXRhaWxz\n" + "IERlcHQuMB4XDTI2MDcwNzEwNTIxNloXDTM2MDcwNDEwNTIxNlowZTEcMBoGA1UE\n" + "AwwTb3Zwbi10ZXN0LXNlY3AzODRyMTEoMCYGA1UECgwfT3BlblZQTiBVbml0IFRl\n" + "c3QgRXhhbXBsZSBDb3JwLjEbMBkGA1UECwwSQ2VydCBEZXRhaWxzIERlcHQuMHYw\n" + "EAYHKoZIzj0CAQYFK4EEACIDYgAEOlKoQVk+wbBD6V/6kg+/oHfqF0Dq08LlCL+B\n" + "om4RhutG99QDrow251Ps+Ds/7LQYYRA8+hHyEFrmGM+j2o6KhS5K2uA6dIZL4zLK\n" + "vl0NeF2M61Z8tt/IjrFZd+CrEANco4GKMIGHMB0GA1UdDgQWBBSEyG6m+QdWazeg\n" + "0CHN7q0edJlqMjAfBgNVHSMEGDAWgBSEyG6m+QdWazeg0CHN7q0edJlqMjAPBgNV\n" + "HRMBAf8EBTADAQH/MB8GA1UdEQQYMBaCFHVuaXR0ZXN0LmV4YW1wbGUuY29tMBMG\n" + "A1UdJQQMMAoGCCsGAQUFBwMCMAoGCCqGSM49BAMCA2cAMGQCMCyK7aQcyKGW8BWQ\n" + "UOYqbJUJZJcviP6ACgJRzK6pgkqt9gY0E0Tb00Qh6D5dBV5i3wIwCMhSgpVJxDrc\n" + "pRfligoK8bmv4HEgnV6BDeoDYd41WVMpE9u1issQDHY0SnWC7d9q\n" + "-----END CERTIFICATE-----\n"; +const char *const cert_details_cname = "ovpn-test-secp384r1"; +const char *const cert_details_org = "OpenVPN Unit Test Example Corp."; +const char *const cert_details_org_unit = "Cert Details Dept."; +const char *const cert_details_serial_number = "229677570263950905252266749734450551528150860362"; +const char *const cert_details_serial_number_hex = "0x283B1933E3C0A4675A0F6405F6261AC68149024A"; + void crypto_test_print_cert_details(void **state) { - openvpn_x509_cert_t *cert = get_certificate(cert1); + openvpn_x509_cert_t *cert = get_certificate(cert_details_test_cert); struct gc_arena gc = gc_new(); const char *fp = backend_x509_get_serial_hex(cert, &gc); @@ -801,29 +828,57 @@ /* we messed this up between TLS libraries. But let's at least notice in * the future ...*/ #if defined(ENABLE_CRYPTO_MBEDTLS) - assert_string_equal(fp, "82:6B:DD:CC:BD:E5:5E:B7:08:F1:2D:68:00:3C:24:DE"); + assert_string_equal(fp, "28:3B:19:33:E3:C0:A4:67:5A:0F:64:05:F6:26:1A:C6:81:49:02:4A"); #else - assert_string_equal(fp, "82:6b:dd:cc:bd:e5:5e:b7:08:f1:2d:68:00:3c:24:de"); + assert_string_equal(fp, "28:3b:19:33:e3:c0:a4:67:5a:0f:64:05:f6:26:1a:c6:81:49:02:4a"); #endif const char *sn = backend_x509_get_serial(cert, &gc); - assert_string_equal(sn, "173359713849739808110610111821055272158"); + assert_string_equal(sn, cert_details_serial_number); char username[TLS_USERNAME_LEN + 1] = { 0 }; /* null-terminated */ - int ret = backend_x509_get_username(username, sizeof(username), "CN", - cert); + int ret = backend_x509_get_username(username, sizeof(username), "CN", cert); - assert_string_equal(username, "ovpn-test-ec1"); + assert_string_equal(username, cert_details_cname); assert_int_equal(ret, SUCCESS); -#ifndef ENABLE_CRYPTO_MBEDTLS - /* mbed TLS does not implement this */ - ret = backend_x509_get_username(username, sizeof(username), "serialNumber", - cert); + ret = backend_x509_get_username(username, sizeof(username), "serialNumber", cert); assert_int_equal(ret, SUCCESS); - assert_string_equal(username, "0x826BDDCCBDE55EB708F12D68003C24DE"); -#endif + assert_string_equal(username, cert_details_serial_number_hex); + + ret = backend_x509_get_username(username, sizeof(username), "O", cert); + + assert_string_equal(username, cert_details_org); + assert_int_equal(ret, SUCCESS); + + ret = backend_x509_get_username(username, sizeof(username), "OU", cert); + + assert_string_equal(username, cert_details_org_unit); + assert_int_equal(ret, SUCCESS); + + /* Check that FAILURE is returned if a field does not exist. */ + ret = backend_x509_get_username(username, sizeof(username), "SN", cert); + assert_int_equal(ret, FAILURE); + + /* Check that FAILURE is returned for invalid field names. */ + ret = backend_x509_get_username(username, sizeof(username), "invalidField", cert); + assert_int_equal(ret, FAILURE); + + /* Check that FAILURE is returned if the output buffer is too small. Do this separately + * for a subject field and for the serial number, because these are different code paths. + * + * First case: Can't fit all characters. */ + ret = backend_x509_get_username(username, strlen(cert_details_cname) / 2, "CN", cert); + assert_int_equal(ret, FAILURE); + ret = backend_x509_get_username(username, strlen(cert_details_serial_number_hex) / 2, "serialNumber", cert); + assert_int_equal(ret, FAILURE); + + /* Second case: Can fit the characters but not the terminating '\0'. */ + ret = backend_x509_get_username(username, strlen(cert_details_cname), "CN", cert); + assert_int_equal(ret, FAILURE); + ret = backend_x509_get_username(username, strlen(cert_details_serial_number_hex), "serialNumber", cert); + assert_int_equal(ret, FAILURE); gc_free(&gc); free_certificate(cert);