int _hx509_Name_to_string(const Name *n, char **str) { size_t total_len = 0; int i, j; *str = strdup(""); if (*str == NULL) return ENOMEM; for (i = n->u.rdnSequence.len - 1 ; i >= 0 ; i--) { int len; 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; break; case choice_DirectoryString_printableString: ss = ds->u.printableString; break; case choice_DirectoryString_utf8String: ss = ds->u.utf8String; break; case choice_DirectoryString_bmpString: { uint16_t *bmp = ds->u.bmpString.data; size_t bmplen = ds->u.bmpString.length; size_t k; ss = malloc(bmplen + 1); if (ss == NULL) _hx509_abort("allocation failure"); /* XXX */ for (k = 0; k < bmplen; k++) ss[k] = bmp[k] & 0xff; /* XXX */ ss[k] = '\0'; break; } case choice_DirectoryString_teletexString: ss = malloc(ds->u.teletexString.length + 1); if (ss == NULL) _hx509_abort("allocation failure"); /* XXX */ memcpy(ss, ds->u.teletexString.data, ds->u.teletexString.length); ss[ds->u.teletexString.length] = '\0'; break; case choice_DirectoryString_universalString: { uint32_t *uni = ds->u.universalString.data; size_t unilen = ds->u.universalString.length; size_t k; ss = malloc(unilen + 1); if (ss == NULL) _hx509_abort("allocation failure"); /* XXX */ for (k = 0; k < unilen; k++) ss[k] = uni[k] & 0xff; /* XXX */ ss[k] = '\0'; 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); len = strlen(ss); append_string(str, &total_len, ss, len, 1); if (ds->element == choice_DirectoryString_universalString || ds->element == choice_DirectoryString_bmpString || ds->element == choice_DirectoryString_teletexString) { 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; }
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; }