int wind_ucs4utf8_copy(const uint32_t *in, size_t in_len, char **out, size_t *out_len) { size_t size; int ret; ret = wind_ucs4utf8_length(in, in_len, &size); if (ret) return ret; size += 1; *out = malloc(size); if (*out == NULL) return ENOMEM; ret = wind_ucs4utf8(in, in_len, *out, &size); if (ret) { free(*out); *out = NULL; return ret; } if (out_len) *out_len = size; return 0; }
int hx509_name_get_component(hx509_name name, int rdn, const heim_oid *type, unsigned *count, char **str) { Name *n = &name->der_name; size_t len, ulen; uint32_t *ds; unsigned i; int ret; if (str) *str = NULL; if (rdn >= n->u.rdnSequence.len) return ERANGE; for (i = *count; i < n->u.rdnSequence.val[rdn].len; i++) { if (der_heim_oid_cmp(&n->u.rdnSequence.val[rdn].val[i].type, type) == 0) { *count = i + 1; if (str == NULL) return HX509_NAME_MALFORMED; ret = dsstringprep(&n->u.rdnSequence.val[rdn].val[i].value, &ds, &len); if (ret) return ret; ret = wind_ucs4utf8_length(ds, len, &ulen); if (ret) { free(ds); return ret; } ulen += 1; *str = malloc(ulen); if (str == NULL) { free(ds); return ENOMEM; } ret = wind_ucs4utf8(ds, len, *str, &ulen); free(ds); if (ret) { free(*str); *str = NULL; return ret; } return 0; } } if (str == NULL) return 0; return HX509_NAME_MALFORMED; }
int _hx509_Name_to_string(const Name *n, char **str) { size_t total_len = 0; size_t i, j, m; int ret; *str = strdup(""); if (*str == NULL) return ENOMEM; for (m = n->u.rdnSequence.len; m > 0; m--) { size_t len; i = m - 1; for (j = 0; j < n->u.rdnSequence.val[i].len; j++) { DirectoryString *ds = &n->u.rdnSequence.val[i].val[j].value; char *oidname; char *ss; oidname = oidtostring(&n->u.rdnSequence.val[i].val[j].type); switch(ds->element) { case choice_DirectoryString_ia5String: ss = ds->u.ia5String.data; len = ds->u.ia5String.length; break; case choice_DirectoryString_printableString: ss = ds->u.printableString.data; len = ds->u.printableString.length; break; case choice_DirectoryString_utf8String: ss = ds->u.utf8String; len = strlen(ss); break; case choice_DirectoryString_bmpString: { const uint16_t *bmp = ds->u.bmpString.data; size_t bmplen = ds->u.bmpString.length; size_t k; ret = wind_ucs2utf8_length(bmp, bmplen, &k); if (ret) { free(oidname); free(*str); *str = NULL; return ret; } ss = malloc(k + 1); if (ss == NULL) _hx509_abort("allocation failure"); /* XXX */ ret = wind_ucs2utf8(bmp, bmplen, ss, NULL); if (ret) { free(oidname); free(ss); free(*str); *str = NULL; return ret; } ss[k] = '\0'; len = k; break; } case choice_DirectoryString_teletexString: ss = ds->u.teletexString; len = strlen(ss); break; case choice_DirectoryString_universalString: { const uint32_t *uni = ds->u.universalString.data; size_t unilen = ds->u.universalString.length; size_t k; ret = wind_ucs4utf8_length(uni, unilen, &k); if (ret) { free(oidname); free(*str); *str = NULL; return ret; } ss = malloc(k + 1); if (ss == NULL) _hx509_abort("allocation failure"); /* XXX */ ret = wind_ucs4utf8(uni, unilen, ss, NULL); if (ret) { free(ss); free(oidname); free(*str); *str = NULL; return ret; } ss[k] = '\0'; len = k; break; } default: _hx509_abort("unknown directory type: %d", ds->element); exit(1); } append_string(str, &total_len, oidname, strlen(oidname), 0); free(oidname); append_string(str, &total_len, "=", 1, 0); append_string(str, &total_len, ss, len, 1); if (ds->element == choice_DirectoryString_bmpString || ds->element == choice_DirectoryString_universalString) { free(ss); } if (j + 1 < n->u.rdnSequence.val[i].len) append_string(str, &total_len, "+", 1, 0); } if (i > 0) append_string(str, &total_len, ",", 1, 0); } return 0; }