]> git.ipfire.org Git - thirdparty/gnutls.git/commitdiff
fixes in the extension handling
authorNikos Mavrogiannopoulos <nmav@redhat.com>
Thu, 11 Sep 2014 16:09:50 +0000 (18:09 +0200)
committerNikos Mavrogiannopoulos <nmav@redhat.com>
Thu, 11 Sep 2014 17:20:23 +0000 (19:20 +0200)
lib/includes/gnutls/x509-ext.h
lib/libgnutls.map
lib/x509/output.c
lib/x509/x509.c
lib/x509/x509_ext.c
src/pkcs11.c

index 54759c5d6bf496941980a338c8aaf4fd69025642..b9b3a6d43e59444fae099ff5a8d19d8080617372 100644 (file)
@@ -111,7 +111,12 @@ int gnutls_x509_ext_export_authority_key_id(gnutls_x509_aki_t,
 int gnutls_x509_ext_import_authority_key_id(const gnutls_datum_t * ext,
                                         gnutls_x509_aki_t,
                                         unsigned int flags);
-                                        
+
+int gnutls_x509_othername_to_virtual(const char *oid, 
+                                    const gnutls_datum_t *othername,
+                                    unsigned int *virt_type,
+                                    gnutls_datum_t *virt);
+
 int gnutls_x509_aki_init(gnutls_x509_aki_t *);
 int gnutls_x509_aki_get_id(gnutls_x509_aki_t, gnutls_datum_t *id);
 int gnutls_x509_aki_get_cert_issuer(gnutls_x509_aki_t aki, unsigned int seq,
index 6fc28174845171a63fba45da6d07b1bc5dfd28b6..79ed206991d9a1228d25c7ff8bbed1b483e03f56 100644 (file)
@@ -1029,6 +1029,7 @@ GNUTLS_3_1_0 {
        gnutls_pkcs11_obj_get_exts;
        gnutls_x509_ext_deinit;
        gnutls_x509_ext_print;
+       gnutls_x509_othername_to_virtual;
 } GNUTLS_3_0_0;
 
 GNUTLS_FIPS140 {
index f7a6ad338f2d4b5ef8a3c73048c82e90ceeb7255..c168a20eb4c1d10ba2030e217fdf4fce03605c09 100644 (file)
@@ -156,7 +156,7 @@ unsigned non_ascii = 0, i;
                break;
 
        case GNUTLS_SAN_OTHERNAME_XMPP:
-               addf(str,  _("%sXMPP: %.*s\n"), prefix, name->size, NON_NULL(name->data));
+               addf(str,  _("%sXMPP Address: %.*s\n"), prefix, name->size, NON_NULL(name->data));
                break;
        default:
                addf(str,  _("%sUnknown name: "), prefix);
@@ -361,24 +361,25 @@ static void print_aki(gnutls_buffer_st * str, gnutls_datum_t *der)
        if (err < 0) {
                addf(str, "error: gnutls_x509_ext_import_authority_key_id: %s\n",
                     gnutls_strerror(err));
-               return;
+               goto cleanup;
        }
 
        err = gnutls_x509_aki_get_id(aki, &id);
-       if (err == GNUTLS_E_X509_UNSUPPORTED_EXTENSION) {
+       if (err == GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE) {
                /* Check if an alternative name is there */
                print_aki_gn_serial(str, aki);
-               return;
+               goto cleanup;
        } else if (err < 0) {
                addf(str, "error: gnutls_x509_aki_get_id: %s\n",
                     gnutls_strerror(err));
-               return;
+               goto cleanup;
        }
        
        adds(str, "\t\t\t");
        _gnutls_buffer_hexprint(str, id.data, id.size);
        adds(str, "\n");
 
+ cleanup:
        gnutls_x509_aki_deinit(aki);
 }
 
@@ -478,14 +479,14 @@ static void print_crldist(gnutls_buffer_st * str, gnutls_datum_t *der)
        if (err < 0) {
                addf(str, "error: gnutls_x509_ext_import_crl_dist_points: %s\n",
                     gnutls_strerror(err));
-               return;
+               goto cleanup;
        }
 
        for (indx = 0;; indx++) {
                err =
                    gnutls_x509_crl_dist_points_get(dp, indx, &type, &dist, &flags);
                if (err == GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE)
-                       return;
+                       goto cleanup;
                else if (err < 0) {
                        addf(str, "error: get_crl_dist_points: %s\n",
                             gnutls_strerror(err));
@@ -494,6 +495,8 @@ static void print_crldist(gnutls_buffer_st * str, gnutls_datum_t *der)
 
                print_name(str, "\t\t\t", type, &dist);
        }
+ cleanup:
+       gnutls_x509_crl_dist_points_deinit(dp);
 }
 
 static void
@@ -516,17 +519,17 @@ print_key_purpose(gnutls_buffer_st * str, const char *prefix, gnutls_datum_t *de
        if (err < 0) {
                addf(str, "error: gnutls_x509_ext_import_key_purposes: %s\n",
                     gnutls_strerror(err));
-               return;
+               goto cleanup;
        }
 
        for (indx = 0;; indx++) {
                err = gnutls_x509_key_purpose_get(purposes, indx, &oid);
                if (err == GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE)
-                       return;
-               else if (err < GNUTLS_E_SHORT_MEMORY_BUFFER) {
+                       goto cleanup;
+               else if (err < 0) {
                        addf(str, "error: gnutls_x509_key_purpose_get: %s\n",
                             gnutls_strerror(err));
-                       return;
+                       goto cleanup;
                }
 
                p = (void*)oid.data;
@@ -550,6 +553,7 @@ print_key_purpose(gnutls_buffer_st * str, const char *prefix, gnutls_datum_t *de
                else
                        addf(str, "%s\t\t\t%s\n", prefix, p);
        }
+ cleanup:
        gnutls_x509_key_purpose_deinit(purposes);
 }
 
@@ -588,6 +592,7 @@ print_altname(gnutls_buffer_st * str, const char *prefix, gnutls_datum_t *der)
        unsigned int type;
        gnutls_datum_t san;
        gnutls_datum_t othername;
+       char pfx[16];
        int err;
 
        err = gnutls_subject_alt_names_init(&names);
@@ -613,10 +618,22 @@ print_altname(gnutls_buffer_st * str, const char *prefix, gnutls_datum_t *der)
                        addf(str,
                             "error: gnutls_subject_alt_names_get: %s\n",
                             gnutls_strerror(err));
-                       return;
+                       break;
                }
 
+
                if (type == GNUTLS_SAN_OTHERNAME) {
+                       unsigned vtype;
+                       gnutls_datum_t virt;
+
+                       err = gnutls_x509_othername_to_virtual((char*)othername.data, &san, &vtype, &virt);
+                       if (err >= 0) {
+                               snprintf(pfx, sizeof(pfx), "%s\t\t\t", prefix);
+                               print_name(str, pfx, vtype, &virt);
+                               gnutls_free(virt.data);
+                               continue;
+                       }
+
                        addf(str,
                             _("%s\t\t\totherName OID: %.*s\n"),
                             prefix, (int)othername.size, (char*)othername.data);
@@ -628,7 +645,6 @@ print_altname(gnutls_buffer_st * str, const char *prefix, gnutls_datum_t *der)
                        _gnutls_buffer_asciiprint(str, (char*)san.data, san.size);
                                addf(str, "\n");
                } else {
-                       char pfx[16];
 
                        snprintf(pfx, sizeof(pfx), "%s\t\t\t", prefix);
                        print_name(str, pfx, type, &san);
@@ -718,7 +734,7 @@ static void print_extension(gnutls_buffer_st * str, const char *prefix,
        if (strcmp(oid, "2.5.29.19") == 0) {
                if (idx->basic) {
                        addf(str,
-                            "error: more than one basic constraint\n");
+                            "warning: more than one basic constraint\n");
                }
 
                addf(str, _("%s\t\tBasic Constraints (%s):\n"),
@@ -731,7 +747,7 @@ static void print_extension(gnutls_buffer_st * str, const char *prefix,
        } else if (strcmp(oid, "2.5.29.14") == 0) {
                if (idx->ski) {
                        addf(str,
-                            "error: more than one SKI extension\n");
+                            "warning: more than one SKI extension\n");
                }
 
                addf(str,
@@ -799,14 +815,13 @@ static void print_extension(gnutls_buffer_st * str, const char *prefix,
                                     prefix, name,
                                     policy.qualifier[j].data);
                        }
-                       gnutls_x509_policy_release(&policy);
                }
                gnutls_x509_policies_deinit(policies);
        } else if (strcmp(oid, "2.5.29.35") == 0) {
 
                if (idx->aki) {
                        addf(str,
-                            "error: more than one AKI extension\n");
+                            "warning: more than one AKI extension\n");
                }
 
                addf(str,
@@ -820,7 +835,7 @@ static void print_extension(gnutls_buffer_st * str, const char *prefix,
        } else if (strcmp(oid, "2.5.29.15") == 0) {
                if (idx->keyusage) {
                        addf(str,
-                            "error: more than one key usage extension\n");
+                            "warning: more than one key usage extension\n");
                }
 
                addf(str, _("%s\t\tKey Usage (%s):\n"), prefix,
@@ -833,7 +848,7 @@ static void print_extension(gnutls_buffer_st * str, const char *prefix,
        } else if (strcmp(oid, "2.5.29.16") == 0) {
                if (idx->pkey_usage_period) {
                        addf(str,
-                            "error: more than one private key usage period extension\n");
+                            "warning: more than one private key usage period extension\n");
                }
 
                addf(str,
@@ -847,7 +862,7 @@ static void print_extension(gnutls_buffer_st * str, const char *prefix,
        } else if (strcmp(oid, "2.5.29.37") == 0) {
                if (idx->keypurpose) {
                        addf(str,
-                            "error: more than one key purpose extension\n");
+                            "warning: more than one key purpose extension\n");
                }
 
                addf(str, _("%s\t\tKey Purpose (%s):\n"), prefix,
@@ -858,7 +873,7 @@ static void print_extension(gnutls_buffer_st * str, const char *prefix,
        } else if (strcmp(oid, "2.5.29.17") == 0) {
                if (idx->san) {
                        addf(str,
-                            "error: more than one SKI extension\n");
+                            "warning: more than one SKI extension\n");
                }
 
                addf(str,
@@ -870,7 +885,7 @@ static void print_extension(gnutls_buffer_st * str, const char *prefix,
        } else if (strcmp(oid, "2.5.29.18") == 0) {
                if (idx->ian) {
                        addf(str,
-                            "error: more than one Issuer AltName extension\n");
+                            "warning: more than one Issuer AltName extension\n");
                }
 
                addf(str,
@@ -884,7 +899,7 @@ static void print_extension(gnutls_buffer_st * str, const char *prefix,
        } else if (strcmp(oid, "2.5.29.31") == 0) {
                if (idx->crldist) {
                        addf(str,
-                            "error: more than one CRL distribution point\n");
+                            "warning: more than one CRL distribution point\n");
                }
 
                addf(str,
@@ -897,7 +912,7 @@ static void print_extension(gnutls_buffer_st * str, const char *prefix,
        } else if (strcmp(oid, "1.3.6.1.5.5.7.1.14") == 0) {
                if (idx->proxy) {
                        addf(str,
-                            "error: more than one proxy extension\n");
+                            "warning: more than one proxy extension\n");
                }
 
                addf(str,
@@ -918,7 +933,7 @@ static void print_extension(gnutls_buffer_st * str, const char *prefix,
        } else if (strcmp(oid, "2.5.29.30") == 0) {
                if (idx->nc) {
                        addf(str,
-                            "error: more than one name constraints extension\n");
+                            "warning: more than one name constraints extension\n");
                }
                idx->nc++;
 
@@ -997,6 +1012,7 @@ print_extensions(gnutls_buffer_st * str, const char *prefix, int type,
                }
 
                print_extension(str, prefix, &idx, oid, critical, &der);
+               gnutls_free(der.data);
        }
 }
 
@@ -1868,8 +1884,7 @@ print_crl(gnutls_buffer_st * str, gnutls_x509_crl_t crl, int notsigned)
 
                                if (crl_nr) {
                                        addf(str,
-                                            "error: more than one CRL number\n");
-                                       continue;
+                                            "warning: more than one CRL number\n");
                                }
 
                                err =
@@ -1897,8 +1912,7 @@ print_crl(gnutls_buffer_st * str, gnutls_x509_crl_t crl, int notsigned)
 
                                if (aki_idx) {
                                        addf(str,
-                                            "error: more than one AKI extension\n");
-                                       continue;
+                                            "warning: more than one AKI extension\n");
                                }
 
                                addf(str,
@@ -2211,8 +2225,7 @@ print_crq(gnutls_buffer_st * str, gnutls_x509_crq_t cert,
 
                                if (extensions) {
                                        addf(str,
-                                            "error: more than one extensionsRequest\n");
-                                       continue;
+                                            "warning: more than one extensionsRequest\n");
                                }
 
                                ccert.crq = cert;
@@ -2227,8 +2240,7 @@ print_crq(gnutls_buffer_st * str, gnutls_x509_crq_t cert,
 
                                if (challenge) {
                                        adds(str,
-                                            "error: more than one Challenge password attribute\n");
-                                       continue;
+                                            "warning: more than one Challenge password attribute\n");
                                }
 
                                err =
@@ -2503,7 +2515,7 @@ gnutls_x509_ext_print(gnutls_x509_ext_st *exts, unsigned int exts_size,
        _gnutls_buffer_init(&str);
 
        for (i=0;i<exts_size;i++)
-               print_extension(&str, "\t", &idx, (char*)exts[i].oid, exts[i].critical, &exts[i].data);
+               print_extension(&str, "", &idx, (char*)exts[i].oid, exts[i].critical, &exts[i].data);
 
        _gnutls_buffer_append_data(&str, "\x00", 1);
 
index 9aa085c69fa3247f667a9575315d8349dc008441..579f0c52a12ea032a4cf8b0e8360679238126605 100644 (file)
@@ -1180,28 +1180,8 @@ _gnutls_parse_general_name2(ASN1_TYPE src, const char *src_name,
                        }
                        if (len > 0) len--;
 
-                       if (_san_othername_to_virtual(oid, len) == GNUTLS_SAN_OTHERNAME_XMPP) {
-                               gnutls_datum_t out;
-
-                               ret =
-                                   _gnutls_x509_decode_string
-                                   (ASN1_ETYPE_UTF8_STRING, tmp.data,
-                                    tmp.size, &out);
-                               if (ret < 0) {
-                                       gnutls_assert();
-                                       goto cleanup;
-                               }
-
-                               dname->data = out.data;
-                               dname->size = out.size;
-
-                               /* out is already null terminated */
-                               ret = type;
-                               goto cleanup;
-                       } else {
-                               dname->size = tmp.size;
-                               dname->data = tmp.data;
-                       }
+                       dname->size = tmp.size;
+                       dname->data = tmp.data;
                }
        } else if (type == GNUTLS_SAN_DN) {
                _gnutls_str_cat(nptr, sizeof(nptr), ".directoryName");
@@ -1322,7 +1302,15 @@ get_alt_name(gnutls_x509_crt_t cert, const char *extension_id,
        }
 
        if (othername_oid && type == GNUTLS_SAN_OTHERNAME) {
-               type = _san_othername_to_virtual((char*)ooid.data, ooid.size);
+               unsigned vtype;
+               gnutls_datum_t virt;
+               ret = gnutls_x509_othername_to_virtual((char*)ooid.data, &res, &vtype, &virt);
+               if (ret >= 0) {
+                       type = vtype;
+                       gnutls_free(res.data);
+                       res.data = virt.data;
+                       res.size = virt.size;
+               }
        }
 
        if (alt_type)
index 5aeceefc9e12cd5a2966d92872b7b48877712d70..58fa55b3af0de33947a1a4062fbcc2117b075b35 100644 (file)
@@ -3119,3 +3119,47 @@ int _gnutls_x509_decode_ext(const gnutls_datum_t *der, gnutls_x509_ext_st *out)
        return ret;
        
 }
+
+/**
+ * gnutls_x509_othername_to_virtual:
+ * @oid: The othername object identifier
+ * @data: The othername data
+ * @virt_type: GNUTLS_SAN_OTHERNAME_XXX
+ * @virt: allocated printable data
+ *
+ * This function will parse and convert the othername data to a virtual
+ * type supported by gnutls.
+ *
+ * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a negative error value.
+ *
+ * Since: 3.3.8
+ **/
+int gnutls_x509_othername_to_virtual(const char *oid, 
+                                    const gnutls_datum_t *othername,
+                                    unsigned int *virt_type,
+                                    gnutls_datum_t *virt)
+{
+       int ret;
+       unsigned type;
+
+       type = _san_othername_to_virtual(oid, strlen(oid));
+       if (type == GNUTLS_SAN_OTHERNAME)
+               return gnutls_assert_val(GNUTLS_E_X509_UNKNOWN_SAN);
+
+       if (virt_type)
+               *virt_type = type;
+
+       switch(type) {
+               case GNUTLS_SAN_OTHERNAME_XMPP:
+                       ret = _gnutls_x509_decode_string
+                                   (ASN1_ETYPE_UTF8_STRING, othername->data,
+                                    othername->size, virt);
+                       if (ret < 0) {
+                               gnutls_assert();
+                               return ret;
+                       }
+                       return 0;
+               default:
+                       return gnutls_assert_val(GNUTLS_E_INTERNAL_ERROR);
+       }
+}
index 6897c1efb77faa2aeeae63ecf82f55f4a21d3b45..462ce202589bb0c21cb7e52a36a6d69ae30e48c1 100644 (file)
@@ -104,13 +104,17 @@ pkcs11_list(FILE * outfile, const char *url, int type, unsigned int flags,
 
        FIX(url, outfile, detailed, info);
 
+       gnutls_pkcs11_token_get_flags(url, &flags);
+       if (flags & GNUTLS_PKCS11_TOKEN_TRUSTED)
+               print_exts = 1;
+
        if (type == PKCS11_TYPE_TRUSTED) {
                attrs = GNUTLS_PKCS11_OBJ_ATTR_CRT_TRUSTED;
        } else if (type == PKCS11_TYPE_PK) {
                attrs = GNUTLS_PKCS11_OBJ_ATTR_CRT_WITH_PRIVKEY;
        } else if (type == PKCS11_TYPE_CRT_ALL) {
                attrs = GNUTLS_PKCS11_OBJ_ATTR_CRT_ALL;
-               print_exts = 1;
+               if (print_exts != 0) print_exts++;
        } else if (type == PKCS11_TYPE_PRIVKEY) {
                attrs = GNUTLS_PKCS11_OBJ_ATTR_PRIVKEY;
        } else if (type == PKCS11_TYPE_INFO) {
@@ -192,12 +196,12 @@ pkcs11_list(FILE * outfile, const char *url, int type, unsigned int flags,
                }
                fprintf(outfile, "\tID: %s\n", buf);
 
-               if (otype == GNUTLS_PKCS11_OBJ_X509_CRT) {
+               if (otype == GNUTLS_PKCS11_OBJ_X509_CRT && print_exts > 0) {
                        ret = gnutls_pkcs11_obj_get_exts(crt_list[i], &exts, &exts_size, 0);
                        if (ret >= 0 && exts_size > 0) {
                                gnutls_datum_t txt;
 
-                               if (print_exts != 0) {
+                               if (print_exts > 1) {
                                        fprintf(outfile, "\tExtensions:\n");
                                        ret = gnutls_x509_ext_print(exts, exts_size, 0, &txt);
                                        if (ret >= 0) {