int hx509_parse_name(hx509_context context, const char *str, hx509_name *name) { const char *p, *q; size_t len; hx509_name n; int ret; *name = NULL; n = calloc(1, sizeof(*n)); if (n == NULL) { hx509_set_error_string(context, 0, ENOMEM, "out of memory"); return ENOMEM; } n->der_name.element = choice_Name_rdnSequence; p = str; while (p != NULL && *p != '\0') { heim_oid oid; int last; q = strchr(p, ','); if (q) { len = (q - p); last = 1; } else { len = strlen(p); last = 0; } q = strchr(p, '='); if (q == NULL) { ret = HX509_PARSING_NAME_FAILED; hx509_set_error_string(context, 0, ret, "missing = in %s", p); goto out; } if (q == p) { ret = HX509_PARSING_NAME_FAILED; hx509_set_error_string(context, 0, ret, "missing name before = in %s", p); goto out; } if ((q - p) > len) { ret = HX509_PARSING_NAME_FAILED; hx509_set_error_string(context, 0, ret, " = after , in %s", p); goto out; } ret = stringtooid(p, q - p, &oid); if (ret) { ret = HX509_PARSING_NAME_FAILED; hx509_set_error_string(context, 0, ret, "unknown type: %.*s", (int)(q - p), p); goto out; } { size_t pstr_len = len - (q - p) - 1; const char *pstr = p + (q - p) + 1; char *r; r = malloc(pstr_len + 1); if (r == NULL) { der_free_oid(&oid); ret = ENOMEM; hx509_set_error_string(context, 0, ret, "out of memory"); goto out; } memcpy(r, pstr, pstr_len); r[pstr_len] = '\0'; ret = _hx509_name_modify(context, &n->der_name, 0, &oid, r); free(r); der_free_oid(&oid); if(ret) goto out; } p += len + last; } *name = n; return 0; out: hx509_name_free(&n); return HX509_NAME_MALFORMED; }
int hx509_parse_name(hx509_context context, const char *str, hx509_name *name) { char *p, *p0, *q, *endp; size_t len; hx509_name n; int ret; *name = NULL; n = calloc(1, sizeof(*n)); if (n == NULL) { hx509_set_error_string(context, 0, ENOMEM, "out of memory"); return ENOMEM; } n->der_name.element = choice_Name_rdnSequence; p0 = p = strdup(str); if (p == NULL) { free(n); hx509_set_error_string(context, 0, ENOMEM, "out of memory"); return ENOMEM; } endp = p + strlen(p); while (p != NULL && *p != '\0') { heim_oid oid; int last; /* unquote the string */ for (q = p; *q != '\0'; q++) { if (q[0] == '\\' && q[1] != '\0') { memmove(q, q + 1, endp - q - 1); endp--; endp[0] = '\0'; } else if (*q == ',') break; } if (*q != '\0') { len = (q - p); last = 1; } else { len = strlen(p); last = 0; } q = strchr(p, '='); if (q == NULL) { ret = HX509_PARSING_NAME_FAILED; hx509_set_error_string(context, 0, ret, "missing = in %s", p); goto out; } if (q == p) { ret = HX509_PARSING_NAME_FAILED; hx509_set_error_string(context, 0, ret, "missing name before = in %s", p); goto out; } if ((size_t)(q - p) > len) { ret = HX509_PARSING_NAME_FAILED; hx509_set_error_string(context, 0, ret, " = after , in %s", p); goto out; } ret = stringtooid(p, q - p, &oid); if (ret) { ret = HX509_PARSING_NAME_FAILED; hx509_set_error_string(context, 0, ret, "unknown type: %.*s", (int)(q - p), p); goto out; } { size_t pstr_len = len - (q - p) - 1; const char *pstr = p + (q - p) + 1; char *r; r = malloc(pstr_len + 1); if (r == NULL) { der_free_oid(&oid); ret = ENOMEM; hx509_set_error_string(context, 0, ret, "out of memory"); goto out; } memcpy(r, pstr, pstr_len); r[pstr_len] = '\0'; ret = _hx509_name_modify(context, &n->der_name, 0, &oid, r); free(r); der_free_oid(&oid); if(ret) goto out; } p += len + last; } free(p0); *name = n; return 0; out: free(p0); hx509_name_free(&n); return HX509_NAME_MALFORMED; }