From: Nikos Mavrogiannopoulos Date: Thu, 11 Sep 2014 16:09:50 +0000 (+0200) Subject: fixes in the extension handling X-Git-Tag: gnutls_3_4_0~951 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=dfd1bed82edf43d56aa4ef2c3e7266199576048e;p=thirdparty%2Fgnutls.git fixes in the extension handling --- diff --git a/lib/includes/gnutls/x509-ext.h b/lib/includes/gnutls/x509-ext.h index 54759c5d6b..b9b3a6d43e 100644 --- a/lib/includes/gnutls/x509-ext.h +++ b/lib/includes/gnutls/x509-ext.h @@ -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, diff --git a/lib/libgnutls.map b/lib/libgnutls.map index 6fc2817484..79ed206991 100644 --- a/lib/libgnutls.map +++ b/lib/libgnutls.map @@ -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 { diff --git a/lib/x509/output.c b/lib/x509/output.c index f7a6ad338f..c168a20eb4 100644 --- a/lib/x509/output.c +++ b/lib/x509/output.c @@ -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 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) diff --git a/lib/x509/x509_ext.c b/lib/x509/x509_ext.c index 5aeceefc9e..58fa55b3af 100644 --- a/lib/x509/x509_ext.c +++ b/lib/x509/x509_ext.c @@ -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); + } +} diff --git a/src/pkcs11.c b/src/pkcs11.c index 6897c1efb7..462ce20258 100644 --- a/src/pkcs11.c +++ b/src/pkcs11.c @@ -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) {