summaryrefslogtreecommitdiff
path: root/lib/x509/common.c
diff options
context:
space:
mode:
Diffstat (limited to 'lib/x509/common.c')
-rw-r--r--lib/x509/common.c46
1 files changed, 40 insertions, 6 deletions
diff --git a/lib/x509/common.c b/lib/x509/common.c
index 6d72338d42..b75cb7055e 100644
--- a/lib/x509/common.c
+++ b/lib/x509/common.c
@@ -31,6 +31,7 @@
#include <x509_b64.h>
#include "x509_int.h"
#include "extras/hex.h"
+#include "str.h"
#include <common.h>
#include <c-ctype.h>
@@ -1327,6 +1328,30 @@ static int is_printable(char p)
return 0;
}
+/* ensures that the UTF8 string we write is properly encoded */
+int _gnutls_x509_write_utf8_value(ASN1_TYPE asn_struct, const char *where,
+ const uint8_t *data, size_t data_size)
+{
+ int ret, result;
+ uint8_t *nrm = _gnutls_normalize_u8_nfc(data, data_size);
+
+ if (nrm == NULL)
+ return gnutls_assert_val(GNUTLS_E_INVALID_UTF8_PASSWORD);
+
+ result = asn1_write_value(asn_struct, where, nrm, strlen((char*)nrm));
+ if (result != ASN1_SUCCESS) {
+ gnutls_assert();
+ ret = _gnutls_asn2err(result);
+ goto cleanup;
+ }
+
+ ret = 0;
+
+ cleanup:
+ gnutls_free(nrm);
+ return ret;
+}
+
static int write_complex_string(ASN1_TYPE asn_struct, const char *where,
const struct oid_to_string *oentry,
const uint8_t * data, size_t data_size)
@@ -1335,7 +1360,7 @@ static int write_complex_string(ASN1_TYPE asn_struct, const char *where,
ASN1_TYPE c2;
int result;
const char *string_type;
- unsigned int i;
+ unsigned int i, utf8_flag = 0;
result =
asn1_create_element(_gnutls_get_pkix(), oentry->asn_desc, &c2);
@@ -1354,6 +1379,7 @@ static int write_complex_string(ASN1_TYPE asn_struct, const char *where,
for (i = 0; i < data_size; i++) {
if (!is_printable(data[i])) {
string_type = "utf8String";
+ utf8_flag = 1;
break;
}
}
@@ -1370,11 +1396,19 @@ static int write_complex_string(ASN1_TYPE asn_struct, const char *where,
_gnutls_str_cpy(tmp, sizeof(tmp), string_type);
- result = asn1_write_value(c2, tmp, data, data_size);
- if (result != ASN1_SUCCESS) {
- gnutls_assert();
- result = _gnutls_asn2err(result);
- goto error;
+ if (utf8_flag) {
+ result = _gnutls_x509_write_utf8_value(c2, tmp, data, data_size);
+ if (result < 0) {
+ gnutls_assert();
+ goto error;
+ }
+ } else {
+ result = asn1_write_value(c2, tmp, data, data_size);
+ if (result != ASN1_SUCCESS) {
+ gnutls_assert();
+ result = _gnutls_asn2err(result);
+ goto error;
+ }
}
result =