summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNikos Mavrogiannopoulos <nmav@gnutls.org>2016-01-08 12:05:18 +0100
committerNikos Mavrogiannopoulos <nmav@gnutls.org>2016-01-08 12:21:35 +0100
commitdb6621c3a3ee626e4ccc9bade10e677c0fa3b318 (patch)
treeebb91317454bce5040eb3908f14c335a0efc87f8
parent3e8ba29e3fa535e106fa3a3205dc7b3e04956489 (diff)
downloadgnutls-db6621c3a3ee626e4ccc9bade10e677c0fa3b318.tar.gz
x509: added flags to enable the encoding of othername data
-rw-r--r--lib/includes/gnutls/x509.h2
-rw-r--r--lib/x509/crq.c27
-rw-r--r--lib/x509/x509_int.h2
-rw-r--r--lib/x509/x509_write.c76
4 files changed, 70 insertions, 37 deletions
diff --git a/lib/includes/gnutls/x509.h b/lib/includes/gnutls/x509.h
index a75d1ba9b7..f0ebe964d3 100644
--- a/lib/includes/gnutls/x509.h
+++ b/lib/includes/gnutls/x509.h
@@ -86,6 +86,8 @@ extern "C" {
#define GNUTLS_FSAN_SET 0
#define GNUTLS_FSAN_APPEND 1
+#define GNUTLS_FSAN_ENCODE_OCTET_STRING (1<<1)
+#define GNUTLS_FSAN_ENCODE_UTF8_STRING (1<<2)
#define GNUTLS_X509EXT_OID_SUBJECT_KEY_ID "2.5.29.14"
#define GNUTLS_X509EXT_OID_KEY_USAGE "2.5.29.15"
diff --git a/lib/x509/crq.c b/lib/x509/crq.c
index 9263595866..af5afec0e0 100644
--- a/lib/x509/crq.c
+++ b/lib/x509/crq.c
@@ -2045,7 +2045,7 @@ gnutls_x509_crq_set_subject_alt_name(gnutls_x509_crq_t crq,
/* Check if the extension already exists.
*/
- if (flags == GNUTLS_FSAN_APPEND) {
+ if (flags & GNUTLS_FSAN_APPEND) {
result =
gnutls_x509_crq_get_extension_by_oid(crq, "2.5.29.17",
0, NULL,
@@ -2143,6 +2143,7 @@ gnutls_x509_crq_set_subject_alt_othername(gnutls_x509_crq_t crq,
{
int result = 0;
gnutls_datum_t der_data = { NULL, 0 };
+ gnutls_datum_t encoded_data = { NULL, 0 };
gnutls_datum_t prev_der_data = { NULL, 0 };
unsigned int critical = 0;
size_t prev_data_size = 0;
@@ -2154,7 +2155,7 @@ gnutls_x509_crq_set_subject_alt_othername(gnutls_x509_crq_t crq,
/* Check if the extension already exists.
*/
- if (flags == GNUTLS_FSAN_APPEND) {
+ if (flags & GNUTLS_FSAN_APPEND) {
result =
gnutls_x509_crq_get_extension_by_oid(crq, "2.5.29.17",
0, NULL,
@@ -2185,8 +2186,7 @@ gnutls_x509_crq_set_subject_alt_othername(gnutls_x509_crq_t crq,
&critical);
if (result < 0) {
gnutls_assert();
- gnutls_free(prev_der_data.data);
- return result;
+ goto finish;
}
break;
@@ -2196,12 +2196,18 @@ gnutls_x509_crq_set_subject_alt_othername(gnutls_x509_crq_t crq,
}
}
+ result = _gnutls_encode_othername_data(flags, data, data_size, &encoded_data);
+ if (result < 0) {
+ gnutls_assert();
+ goto finish;
+ }
+
/* generate the extension.
*/
- result = _gnutls_x509_ext_gen_subject_alt_name(GNUTLS_SAN_OTHERNAME, oid, data, data_size,
+ result = _gnutls_x509_ext_gen_subject_alt_name(GNUTLS_SAN_OTHERNAME, oid,
+ encoded_data.data, encoded_data.size,
&prev_der_data,
&der_data);
- gnutls_free(prev_der_data.data);
if (result < 0) {
gnutls_assert();
goto finish;
@@ -2211,16 +2217,17 @@ gnutls_x509_crq_set_subject_alt_othername(gnutls_x509_crq_t crq,
_gnutls_x509_crq_set_extension(crq, "2.5.29.17", &der_data,
critical);
- _gnutls_free_datum(&der_data);
-
if (result < 0) {
gnutls_assert();
- return result;
+ goto finish;
}
- return 0;
+ result = 0;
finish:
+ _gnutls_free_datum(&prev_der_data);
+ _gnutls_free_datum(&der_data);
+ _gnutls_free_datum(&encoded_data);
return result;
}
diff --git a/lib/x509/x509_int.h b/lib/x509/x509_int.h
index af07c5297c..3fce6ee7b9 100644
--- a/lib/x509/x509_int.h
+++ b/lib/x509/x509_int.h
@@ -177,6 +177,8 @@ int _gnutls_x509_get_dn_oid(ASN1_TYPE asn1_struct,
const char *asn1_rdn_name,
int indx, void *_oid, size_t * sizeof_oid);
+int _gnutls_encode_othername_data(unsigned flags, const void *data, unsigned data_size, gnutls_datum_t *output);
+
int _gnutls_parse_general_name(ASN1_TYPE src, const char *src_name,
int seq, void *name, size_t * name_size,
unsigned int *ret_type, int othername_oid);
diff --git a/lib/x509/x509_write.c b/lib/x509/x509_write.c
index d2dd3d8258..3c8b77641d 100644
--- a/lib/x509/x509_write.c
+++ b/lib/x509/x509_write.c
@@ -614,7 +614,7 @@ gnutls_x509_crt_set_subject_alt_name(gnutls_x509_crt_t crt,
/* Check if the extension already exists.
*/
- if (flags == GNUTLS_FSAN_APPEND) {
+ if (flags & GNUTLS_FSAN_APPEND) {
result =
_gnutls_x509_crt_get_extension(crt, "2.5.29.17", 0,
&prev_der_data,
@@ -633,9 +633,6 @@ gnutls_x509_crt_set_subject_alt_name(gnutls_x509_crt_t crt,
&prev_der_data,
&der_data);
- if (flags == GNUTLS_FSAN_APPEND)
- _gnutls_free_datum(&prev_der_data);
-
if (result < 0) {
gnutls_assert();
goto finish;
@@ -654,7 +651,7 @@ gnutls_x509_crt_set_subject_alt_name(gnutls_x509_crt_t crt,
crt->use_extensions = 1;
- return 0;
+ result = 0;
finish:
_gnutls_free_datum(&prev_der_data);
@@ -697,7 +694,7 @@ gnutls_x509_crt_set_issuer_alt_name(gnutls_x509_crt_t crt,
/* Check if the extension already exists.
*/
- if (flags == GNUTLS_FSAN_APPEND) {
+ if (flags & GNUTLS_FSAN_APPEND) {
result =
_gnutls_x509_crt_get_extension(crt, "2.5.29.18", 0,
&prev_der_data,
@@ -716,9 +713,6 @@ gnutls_x509_crt_set_issuer_alt_name(gnutls_x509_crt_t crt,
&prev_der_data,
&der_data);
- if (flags == GNUTLS_FSAN_APPEND)
- _gnutls_free_datum(&prev_der_data);
-
if (result < 0) {
gnutls_assert();
goto finish;
@@ -737,13 +731,28 @@ gnutls_x509_crt_set_issuer_alt_name(gnutls_x509_crt_t crt,
crt->use_extensions = 1;
- return 0;
+ result = 0;
finish:
_gnutls_free_datum(&prev_der_data);
return result;
}
+int _gnutls_encode_othername_data(unsigned flags, const void *data, unsigned data_size, gnutls_datum_t *output)
+{
+ int ret;
+ if (flags & GNUTLS_FSAN_ENCODE_OCTET_STRING) {
+ ret = _gnutls_x509_encode_string(ASN1_ETYPE_OCTET_STRING,
+ data, data_size, output);
+ } else if (flags & GNUTLS_FSAN_ENCODE_UTF8_STRING) {
+ ret = _gnutls_x509_encode_string(ASN1_ETYPE_UTF8_STRING,
+ data, data_size, output);
+ } else {
+ ret = _gnutls_set_datum(output, data, data_size);
+ }
+ return ret;
+}
+
/**
* gnutls_x509_crt_set_subject_alt_othername:
* @crt: a certificate of type #gnutls_x509_crt_t
@@ -756,6 +765,8 @@ gnutls_x509_crt_set_issuer_alt_name(gnutls_x509_crt_t crt,
* extension.
*
* The values set are set as binary values and are expected to have the proper DER encoding.
+ * For convenience the flags %GNUTLS_FSAN_ENCODE_OCTET_STRING and %GNUTLS_FSAN_ENCODE_UTF8_STRING
+ * can be used to encode the provided data.
*
* Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
* negative error value.
@@ -772,6 +783,7 @@ gnutls_x509_crt_set_subject_alt_othername(gnutls_x509_crt_t crt,
int result;
gnutls_datum_t der_data = { NULL, 0 };
gnutls_datum_t prev_der_data = { NULL, 0 };
+ gnutls_datum_t encoded_data = { NULL, 0 };
unsigned int critical = 0;
if (crt == NULL) {
@@ -782,7 +794,7 @@ gnutls_x509_crt_set_subject_alt_othername(gnutls_x509_crt_t crt,
/* Check if the extension already exists.
*/
- if (flags == GNUTLS_FSAN_APPEND) {
+ if (flags & GNUTLS_FSAN_APPEND) {
result =
_gnutls_x509_crt_get_extension(crt, "2.5.29.17", 0,
&prev_der_data,
@@ -794,17 +806,20 @@ gnutls_x509_crt_set_subject_alt_othername(gnutls_x509_crt_t crt,
}
}
+ result = _gnutls_encode_othername_data(flags, data, data_size, &encoded_data);
+ if (result < 0) {
+ gnutls_assert();
+ goto finish;
+ }
+
/* generate the extension.
*/
result =
_gnutls_x509_ext_gen_subject_alt_name(GNUTLS_SAN_OTHERNAME, oid,
- data, data_size,
+ encoded_data.data, encoded_data.size,
&prev_der_data,
&der_data);
- if (flags == GNUTLS_FSAN_APPEND)
- _gnutls_free_datum(&prev_der_data);
-
if (result < 0) {
gnutls_assert();
goto finish;
@@ -814,19 +829,20 @@ gnutls_x509_crt_set_subject_alt_othername(gnutls_x509_crt_t crt,
_gnutls_x509_crt_set_extension(crt, "2.5.29.17", &der_data,
critical);
- _gnutls_free_datum(&der_data);
if (result < 0) {
gnutls_assert();
- return result;
+ goto finish;
}
crt->use_extensions = 1;
- return 0;
+ result = 0;
finish:
+ _gnutls_free_datum(&der_data);
_gnutls_free_datum(&prev_der_data);
+ _gnutls_free_datum(&encoded_data);
return result;
}
@@ -842,6 +858,8 @@ gnutls_x509_crt_set_subject_alt_othername(gnutls_x509_crt_t crt,
* extension.
*
* The values set are set as binary values and are expected to have the proper DER encoding.
+ * For convenience the flags %GNUTLS_FSAN_ENCODE_OCTET_STRING and %GNUTLS_FSAN_ENCODE_UTF8_STRING
+ * can be used to encode the provided data.
*
* Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
* negative error value.
@@ -858,6 +876,7 @@ gnutls_x509_crt_set_issuer_alt_othername(gnutls_x509_crt_t crt,
int result;
gnutls_datum_t der_data = { NULL, 0 };
gnutls_datum_t prev_der_data = { NULL, 0 };
+ gnutls_datum_t encoded_data = {NULL, 0};
unsigned int critical = 0;
if (crt == NULL) {
@@ -868,7 +887,7 @@ gnutls_x509_crt_set_issuer_alt_othername(gnutls_x509_crt_t crt,
/* Check if the extension already exists.
*/
- if (flags == GNUTLS_FSAN_APPEND) {
+ if (flags & GNUTLS_FSAN_APPEND) {
result =
_gnutls_x509_crt_get_extension(crt, "2.5.29.18", 0,
&prev_der_data,
@@ -880,17 +899,20 @@ gnutls_x509_crt_set_issuer_alt_othername(gnutls_x509_crt_t crt,
}
}
+ result = _gnutls_encode_othername_data(flags, data, data_size, &encoded_data);
+ if (result < 0) {
+ gnutls_assert();
+ goto finish;
+ }
+
/* generate the extension.
*/
result =
_gnutls_x509_ext_gen_subject_alt_name(GNUTLS_SAN_OTHERNAME, oid,
- data, data_size,
+ encoded_data.data, encoded_data.size,
&prev_der_data,
&der_data);
- if (flags == GNUTLS_FSAN_APPEND)
- _gnutls_free_datum(&prev_der_data);
-
if (result < 0) {
gnutls_assert();
goto finish;
@@ -900,19 +922,19 @@ gnutls_x509_crt_set_issuer_alt_othername(gnutls_x509_crt_t crt,
_gnutls_x509_crt_set_extension(crt, "2.5.29.18", &der_data,
critical);
- _gnutls_free_datum(&der_data);
-
if (result < 0) {
gnutls_assert();
- return result;
+ goto finish;
}
crt->use_extensions = 1;
- return 0;
+ result = 0;
finish:
+ _gnutls_free_datum(&der_data);
_gnutls_free_datum(&prev_der_data);
+ _gnutls_free_datum(&encoded_data);
return result;
}