]> git.ipfire.org Git - thirdparty/gnutls.git/commitdiff
Support for Generalname registeredID from RFC 5280 in subject alt name
authorKarsten Ohme <k_o_@users.sourceforge.net>
Fri, 21 Jun 2019 22:39:56 +0000 (00:39 +0200)
committerNikos Mavrogiannopoulos <nmav@redhat.com>
Mon, 22 Jul 2019 07:50:10 +0000 (09:50 +0200)
Added test certificates (cert10.der) with registered ID

Updated Makefile for inclusion of test certificates

Updated SAN unknown test certificates (cert5.der)

Signed-off-by: Karsten Ohme <k_o_@users.sourceforge.net>
NEWS
lib/includes/gnutls/gnutls.h.in
lib/x509/common.c
lib/x509/extensions.c
lib/x509/output.c
lib/x509/x509.c
tests/Makefile.am
tests/certs-interesting/cert10.der [new file with mode: 0644]
tests/certs-interesting/cert5.der
tests/crt_apis.c

diff --git a/NEWS b/NEWS
index 5a3dcb325705a693e2e878afa0c3274d75d7ba31..ed1b0dec445fb80c40337b62812cee171d4ef44e 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -22,6 +22,8 @@ See the end for copying conditions.
 ** libgnutls: gnutls_privkey_sign_hash2 now accepts the GNUTLS_PRIVKEY_SIGN_FLAG_TLS1_RSA
    flag as documented. This makes it a complete replacement of gnutls_privkey_sign_hash().
 
+** libgnutls: Added support for Generalname registeredID.
+
 ** The priority configuration was enhanced to allow more elaborate
    system-wide configuration of the library (#587).
    The following changes were included:
@@ -55,6 +57,7 @@ gnutls_hmac_copy: Added
 GNUTLS_MAC_AES_GMAC_128: Added
 GNUTLS_MAC_AES_GMAC_192: Added
 GNUTLS_MAC_AES_CMAC_256: Added
+GNUTLS_SAN_REGISTERED_ID: Added
 
 
 * Version 3.6.8 (released 2019-05-28)
index 11652a8c2bebe394367cba63c3d03964bf22d252..15f4ac048bea339825ae300d7a6335a4c15a397a 100644 (file)
@@ -2579,6 +2579,7 @@ gnutls_psk_set_server_params_function(gnutls_psk_server_credentials_t
  * @GNUTLS_SAN_IPADDRESS: IP address SAN.
  * @GNUTLS_SAN_OTHERNAME: OtherName SAN.
  * @GNUTLS_SAN_DN: DN SAN.
+ * @GNUTLS_SAN_REGISTERED_ID: RegisteredID.
  * @GNUTLS_SAN_OTHERNAME_XMPP: Virtual SAN, used by certain functions for convenience.
  * @GNUTLS_SAN_OTHERNAME_KRB5PRINCIPAL: Virtual SAN, used by certain functions for convenience.
  *
@@ -2591,7 +2592,8 @@ typedef enum gnutls_x509_subject_alt_name_t {
        GNUTLS_SAN_IPADDRESS = 4,
        GNUTLS_SAN_OTHERNAME = 5,
        GNUTLS_SAN_DN = 6,
-       GNUTLS_SAN_MAX = GNUTLS_SAN_DN,
+       GNUTLS_SAN_REGISTERED_ID = 7,
+       GNUTLS_SAN_MAX = GNUTLS_SAN_REGISTERED_ID,
        /* The following are "virtual" subject alternative name types, in
           that they are represented by an otherName value and an OID.
           Used by gnutls_x509_crt_get_subject_alt_othername_oid.  */
index 4669d37ad582382cdc02884af0d64971e21943c2..3f1a1776c447e64bd30995503ae0e3989250c9b4 100644 (file)
@@ -537,6 +537,9 @@ gnutls_x509_subject_alt_name_t _gnutls_x509_san_find_type(char *str_type)
                return GNUTLS_SAN_OTHERNAME;
        if (strcmp(str_type, "directoryName") == 0)
                return GNUTLS_SAN_DN;
+       if (strcmp(str_type, "registeredID") == 0)
+               return GNUTLS_SAN_REGISTERED_ID;
+
        return (gnutls_x509_subject_alt_name_t) - 1;
 }
 
@@ -703,6 +706,8 @@ x509_read_value(ASN1_TYPE c, const char *root,
        if (result == 0 && allow_null == 0 && len == 0) {
                /* don't allow null strings */
                return gnutls_assert_val(GNUTLS_E_ASN1_DER_ERROR);
+       } else if (result == 0 && allow_null == 0 && etype == ASN1_ETYPE_OBJECT_ID && len == 1) {
+               return gnutls_assert_val(GNUTLS_E_ASN1_DER_ERROR);
        }
 
        if (result != ASN1_MEM_ERROR) {
index 8506da2b93f033d69b4325b02eb09e05715f7b26..c9fef21a1290ea3d58c46c61db8ac81b2517ec50 100644 (file)
@@ -715,6 +715,9 @@ _gnutls_write_general_name(ASN1_TYPE ext, const char *ext_name,
        case GNUTLS_SAN_IPADDRESS:
                str = "iPAddress";
                break;
+       case GNUTLS_SAN_REGISTERED_ID:
+               str = "registeredID";
+               break;
        default:
                gnutls_assert();
                return GNUTLS_E_INTERNAL_ERROR;
index 6c5055cf225f7c1357d3a25273de07a8433c5976..40ba77b7ea72ed2c39e92853f3a8a72e8ed3fea0 100644 (file)
@@ -144,6 +144,10 @@ print_name(gnutls_buffer_st *str, const char *prefix, unsigned type, gnutls_datu
                addf(str,  _("%sdirectoryName: %.*s\n"), prefix, name->size, NON_NULL(name->data));
                break;
 
+       case GNUTLS_SAN_REGISTERED_ID:
+                       addf(str,  _("%sRegistered ID: %.*s\n"), prefix, name->size, NON_NULL(name->data));
+                       break;
+
        case GNUTLS_SAN_OTHERNAME_XMPP:
                addf(str,  _("%sXMPP Address: %.*s\n"), prefix, name->size, NON_NULL(name->data));
                break;
index 26055e08a30cd27405c623ce897b87c99fe83e21..48ab2a7526519a328c2fdd73f75d47f348c1a651 100644 (file)
@@ -1344,7 +1344,7 @@ inline static int is_type_printable(int type)
 {
        if (type == GNUTLS_SAN_DNSNAME || type == GNUTLS_SAN_RFC822NAME ||
            type == GNUTLS_SAN_URI || type == GNUTLS_SAN_OTHERNAME_XMPP ||
-           type == GNUTLS_SAN_OTHERNAME)
+           type == GNUTLS_SAN_OTHERNAME || type == GNUTLS_SAN_REGISTERED_ID)
                return 1;
        else
                return 0;
@@ -1657,7 +1657,6 @@ _gnutls_parse_general_name2(ASN1_TYPE src, const char *src_name,
 
        len = sizeof(choice_type);
        result = asn1_read_value(src, nptr, choice_type, &len);
-
        if (result == ASN1_VALUE_NOT_FOUND
            || result == ASN1_ELEMENT_NOT_FOUND) {
                return GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE;
@@ -1739,6 +1738,12 @@ _gnutls_parse_general_name2(ASN1_TYPE src, const char *src_name,
                        return ret;
                }
 
+               if (type == GNUTLS_SAN_REGISTERED_ID && tmp.size > 0) {
+                       /* see #805; OIDs contain the null termination byte */
+                       assert(tmp.data[tmp.size-1] == 0);
+                       tmp.size--;
+               }
+
                /* _gnutls_x509_read_value() null terminates */
                dname->size = tmp.size;
                dname->data = tmp.data;
index 34e3c5a9700e1719e8af18a372af130ba6f08749..7970ad6b301710d8ff6c896254432ee8790a01a1 100644 (file)
@@ -50,9 +50,9 @@ EXTRA_DIST = suppressions.valgrind eagain-common.h cert-common.h test-chains.h \
        certs-interesting/README.md certs-interesting/cert1.der certs-interesting/cert1.der.err \
        certs-interesting/cert2.der certs-interesting/cert2.der.err certs-interesting/cert3.der \
        certs-interesting/cert3.der.err certs-interesting/cert4.der certs-interesting/cert5.der \
-       certs-interesting/cert6.der certs-interesting/cert6.der.err \
+       certs-interesting/cert5.der.err certs-interesting/cert6.der certs-interesting/cert6.der.err \
        certs-interesting/cert7.der certs-interesting/cert8.der \
-       certs-interesting/cert9.der certs-interesting/cert5.der.err \
+       certs-interesting/cert9.der certs-interesting/cert10.der \
        certs-interesting/cert3.der.err certs-interesting/cert4.der \
        scripts/common.sh scripts/starttls-common.sh \
        rng-op.c x509sign-verify-common.h common-key-tests.h \
diff --git a/tests/certs-interesting/cert10.der b/tests/certs-interesting/cert10.der
new file mode 100644 (file)
index 0000000..07ab16d
Binary files /dev/null and b/tests/certs-interesting/cert10.der differ
index 44b3f0e4df01756b1434aa3cace895b7d3ded5ca..f950ff3e1b1c3bdac0afcafc21301dc49041d298 100644 (file)
Binary files a/tests/certs-interesting/cert5.der and b/tests/certs-interesting/cert5.der differ
index cf0c7fd800343c51d874f4b8ee2c427d946b9e5f..e62ec90d9aee972e2cc3d5ae713ac0bfa61ce1a5 100644 (file)
 
 static unsigned char saved_crt_pem[] =
        "-----BEGIN CERTIFICATE-----\n"
-       "MIICWTCCAcKgAwIBAgIDChEAMA0GCSqGSIb3DQEBCwUAMCsxDjAMBgNVBAMTBW5p\n"
+       "MIICWjCCAcOgAwIBAgIDChEAMA0GCSqGSIb3DQEBCwUAMCsxDjAMBgNVBAMTBW5p\n"
        "a29zMRkwFwYDVQQKExBub25lIHRvLCBtZW50aW9uMCAXDTA4MDMzMTIyMDAwMFoY\n"
        "Dzk5OTkxMjMxMjM1OTU5WjArMQ4wDAYDVQQDEwVuaWtvczEZMBcGA1UEChMQbm9u\n"
        "ZSB0bywgbWVudGlvbjCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEAu2ZD9fLF\n"
        "17aMzMXf9Yg7sclLag6hrSBQQAiAoU9co9D4bM/mPPfsBHYTF4tkiSJbwN1TfDvt\n"
        "fAS7gLkovo6bxo6gpRLL9Vceoue7tzNJn+O7Sq5qTWj/yRHiMo3OPYALjXXv2ACB\n"
-       "jygEA6AijWEEB/q2N30hB0nSCWFpmJCjWKkCAwEAAYEFAAABAgOCBQAEAwIBo3sw\n"
-       "eTAMBgNVHRMBAf8EAjAAMA8GA1UdDwEB/wQFAwMHgAAwNgYDVR0RBC8wLYIDYXBh\n"
-       "ghF4bi0tbXhhYTRhczZkLmNvbYETdGVzdEB4bi0ta3hhd2hrLm9yZzAgBgNVHSUB\n"
-       "Af8EFjAUBggrBgEFBQcDAQYIKwYBBQUHAwIwDQYJKoZIhvcNAQELBQADgYEAsCHT\n"
-       "vpIFkQG8th0DbEU3BE3KP5aa93HDLpZPu5PVLkoBb4PPWjKPK+737mwaSs9zXe58\n"
-       "awhM0ycZ1ymSC+MiRuQlzt4Opx1Fm8WFsDr7d0g/C96Arr1Ss4ZhNi15nyoYeaWJ\n"
-       "1n7nX+msWnuc+aABt1d8aAhAvaU8do0+WI2jY90=\n"
+       "jygEA6AijWEEB/q2N30hB0nSCWFpmJCjWKkCAwEAAYEFAAABAgOCBQAEAwIBo3ww\n"
+       "ejAMBgNVHRMBAf8EAjAAMA8GA1UdDwEB/wQFAwMHgAAwNwYDVR0RBDAwLogEKgME\n"
+       "BYIReG4tLW14YWE0YXM2ZC5jb22BE3Rlc3RAeG4tLWt4YXdoay5vcmcwIAYDVR0l\n"
+       "AQH/BBYwFAYIKwYBBQUHAwEGCCsGAQUFBwMCMA0GCSqGSIb3DQEBCwUAA4GBADzP\n"
+       "piA0s50R+oM/OWcHrARRMFhmOv8oj4mQeXjePCUJub8CDj1XnZwseIY9K9IU6Lxm\n"
+       "43p7kw1jFzPRBJyuZC5X92AdG1meR1RKd91M3VEvn2cgfesX7/MbhZIYJ8ZD2S1L\n"
+       "rqzVabXTZjKdHT727mCJdqzjDh7CFmb9Q2ZU6jDR\n"
        "-----END CERTIFICATE-----\n";
 
 const gnutls_datum_t saved_crt = { saved_crt_pem, sizeof(saved_crt_pem)-1 };
@@ -71,6 +71,8 @@ static time_t mytime(time_t * t)
        return then;
 }
 
+#define REGISTERED_OID "1.2.3.4.5"
+
 void doit(void)
 {
        gnutls_x509_privkey_t pkey;
@@ -79,9 +81,9 @@ void doit(void)
        const char *err = NULL;
        unsigned char buf[64];
        unsigned char large_buf[5*1024];
-       unsigned int status;
+       unsigned int status, san_type;
        gnutls_datum_t out;
-       size_t s = 0;
+       size_t s = 0, i;
        int ret;
 
        ret = global_init();
@@ -181,6 +183,11 @@ void doit(void)
        if (ret != 0)
                fail("gnutls_x509_crt_set_subject_alt_name\n");
 
+       ret = gnutls_x509_crt_set_subject_alt_name(crt, GNUTLS_SAN_REGISTERED_ID,
+                                                  REGISTERED_OID, strlen(REGISTERED_OID), 0);
+       if (ret != 0)
+               fail("gnutls_x509_crt_set_subject_alt_name\n");
+
        ret = gnutls_x509_crt_set_subject_alt_name(crt, GNUTLS_SAN_DNSNAME,
                                                   "απαλό.com", strlen("απαλό.com"), 1);
 #if defined(HAVE_LIBIDN2) || defined(HAVE_LIBIDN)
@@ -355,6 +362,28 @@ void doit(void)
        assert(s == out.size);
        assert(memcmp(large_buf, out.data, out.size) == 0);
 
+       /* verify some values written in the original cert */
+       gnutls_x509_crt_deinit(crt2);
+       ret = gnutls_x509_crt_init(&crt2);
+       if (ret != 0)
+               fail("gnutls_x509_crt_init\n");
+
+       ret = gnutls_x509_crt_import(crt2, &out, GNUTLS_X509_FMT_DER);
+       if (ret != 0)
+               fail("gnutls_x509_crt_import\n");
+
+       i = 0;
+       do {
+               s = sizeof(buf);
+               ret = gnutls_x509_crt_get_subject_alt_name2(crt2, i++, buf, &s, &san_type, NULL);
+               if (ret < 0)
+                       fail("gnutls_x509_crt_get_subject_alt_name2: %s\n", gnutls_strerror(ret));
+       } while (san_type != GNUTLS_SAN_REGISTERED_ID);
+
+       assert(san_type == GNUTLS_SAN_REGISTERED_ID);
+       assert(s == strlen(REGISTERED_OID));
+       assert(memcmp(buf, REGISTERED_OID, s) == 0);
+
        gnutls_free(out.data);
 
        gnutls_x509_crt_deinit(crt);