diff options
author | Lutz Jänicke <jaenicke@openssl.org> | 2002-04-30 12:08:18 +0000 |
---|---|---|
committer | Lutz Jänicke <jaenicke@openssl.org> | 2002-04-30 12:08:18 +0000 |
commit | c0455cbb180e4662a734f11dbcb1f94beb2376a9 (patch) | |
tree | 8079a60de3a556c71a347f3ff9f32d3bf387140f /apps/req.c | |
parent | 17e2c77a7747981cc2470749b5e02b981df72188 (diff) |
Fix escaping when using the -subj option of "openssl req", document
'hidden' -nameopt support. (Robert Joop <joop@fokus.gmd.de>)
Diffstat (limited to 'apps/req.c')
-rw-r--r-- | apps/req.c | 131 |
1 files changed, 96 insertions, 35 deletions
diff --git a/apps/req.c b/apps/req.c index 629a604490..db3dcb80e6 100644 --- a/apps/req.c +++ b/apps/req.c @@ -505,6 +505,7 @@ bad: BIO_printf(bio_err," -extensions .. specify certificate extension section (override value in config file)\n"); BIO_printf(bio_err," -reqexts .. specify request extension section (override value in config file)\n"); BIO_printf(bio_err," -utf8 input characters are UTF8 (default ASCII)\n"); + BIO_printf(bio_err," -nameopt arg - various certificate name options\n"); goto end; } @@ -1210,66 +1211,126 @@ err: return(ret); } +/* + * subject is expected to be in the format /type0=value0/type1=value1/type2=... + * where characters may be escaped by \ + */ static int build_subject(X509_REQ *req, char *subject, unsigned long chtype) { - X509_NAME *n = NULL; - - int i, nid, ne_num=0; + size_t buflen = strlen (subject)+1; /* to copy the types and values into. due to escaping, the copy can only become shorter */ + char *buf = malloc (buflen); + size_t max_ne = buflen / 2 + 1; /* maximum number of name elements */ + char **ne_types = malloc (max_ne * sizeof (char *)); + char **ne_values = malloc (max_ne * sizeof (char *)); - char *ne_name = NULL; - char *ne_value = NULL; + char *sp = subject, *bp = buf; + int i, ne_num = 0; - char *tmp = NULL; - char *p[2]; + X509_NAME *n = NULL; + int nid; - char *str_list[256]; - - p[0] = ",/"; - p[1] = "="; + if (!buf || !ne_types || !ne_values) + { + BIO_printf(bio_err, "malloc error\n"); + goto error0; + } - n = X509_NAME_new(); + if (*subject != '/') + { + BIO_printf(bio_err, "Subject does not start with '/'.\n"); + goto error0; + } + sp++; /* skip leading / */ - tmp = strtok(subject, p[0]); - while((tmp != NULL) && (ne_num < (sizeof str_list/sizeof *str_list))) + while (*sp) + { + /* collect type */ + ne_types[ne_num] = bp; + while (*sp) { - char *token = tmp; - - while (token[0] == ' ') - token++; - str_list[ne_num] = token; - - tmp = strtok(NULL, p[0]); - ne_num++; + if (*sp == '\\') /* is there anything to escape in the type...? */ + if (*++sp) + *bp++ = *sp++; + else + { + BIO_printf(bio_err, "escape character at end of string\n"); + goto error0; + } + else if (*sp == '=') + { + sp++; + *bp++ = '\0'; + break; + } + else + *bp++ = *sp++; + } + if (!*sp) + { + BIO_printf(bio_err, "end of string encountered while processing type of subject name element #%d\n", ne_num); + goto error0; + } + ne_values[ne_num] = bp; + while (*sp) + { + if (*sp == '\\') + if (*++sp) + *bp++ = *sp++; + else + { + BIO_printf(bio_err, "escape character at end of string\n"); + goto error0; + } + else if (*sp == '/') + { + sp++; + *bp++ = '\0'; + break; + } + else + *bp++ = *sp++; } + *bp++ = '\0'; + ne_num++; + } + + if (!(n = X509_NAME_new())) + goto error0; for(i = 0; i < ne_num; i++) { - ne_name = strtok(str_list[i], p[1]); - ne_value = strtok(NULL, p[1]); - - if ((nid=OBJ_txt2nid(ne_name)) == NID_undef) + if ((nid=OBJ_txt2nid(ne_types[i])) == NID_undef) { - BIO_printf(bio_err, "Subject Attribute %s has no known NID, skipped\n", ne_name); + BIO_printf(bio_err, "Subject Attribute %s has no known NID, skipped\n", ne_types[i]); continue; } - if (ne_value == NULL) + if (!*ne_values[i]) { - BIO_printf(bio_err, "No value provided for Subject Attribute %s, skipped\n", ne_name); + BIO_printf(bio_err, "No value provided for Subject Attribute %s, skipped\n", ne_types[i]); continue; } - if (!X509_NAME_add_entry_by_NID(n, nid, chtype, (unsigned char*)ne_value, -1,-1,0)) - { - X509_NAME_free(n); - return 0; - } + if (!X509_NAME_add_entry_by_NID(n, nid, chtype, (unsigned char*)ne_values[i], -1,-1,0)) + goto error1; + } if (!X509_REQ_set_subject_name(req, n)) - return 0; + goto error1; X509_NAME_free(n); + free (ne_values); + free (ne_types); + free (buf); return 1; + +error1: + X509_NAME_free(n); +error0: + free (ne_values); + free (ne_types); + free (buf); + return 0; } |