v3_pci.c 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317
  1. /* v3_pci.c -*- mode:C; c-file-style: "eay" -*- */
  2. /*
  3. * Contributed to the OpenSSL Project 2004 by Richard Levitte
  4. * (richard@levitte.org)
  5. */
  6. /* Copyright (c) 2004 Kungliga Tekniska Högskolan
  7. * (Royal Institute of Technology, Stockholm, Sweden).
  8. * All rights reserved.
  9. *
  10. * Redistribution and use in source and binary forms, with or without
  11. * modification, are permitted provided that the following conditions
  12. * are met:
  13. *
  14. * 1. Redistributions of source code must retain the above copyright
  15. * notice, this list of conditions and the following disclaimer.
  16. *
  17. * 2. Redistributions in binary form must reproduce the above copyright
  18. * notice, this list of conditions and the following disclaimer in the
  19. * documentation and/or other materials provided with the distribution.
  20. *
  21. * 3. Neither the name of the Institute nor the names of its contributors
  22. * may be used to endorse or promote products derived from this software
  23. * without specific prior written permission.
  24. *
  25. * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
  26. * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  27. * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  28. * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
  29. * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  30. * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
  31. * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  32. * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  33. * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  34. * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  35. * SUCH DAMAGE.
  36. */
  37. #include <stdio.h>
  38. #include "cryptlib.h"
  39. #include <openssl/conf.h>
  40. #include <openssl/x509v3.h>
  41. static int i2r_pci(X509V3_EXT_METHOD *method, PROXY_CERT_INFO_EXTENSION *ext,
  42. BIO *out, int indent);
  43. static PROXY_CERT_INFO_EXTENSION *r2i_pci(X509V3_EXT_METHOD *method,
  44. X509V3_CTX *ctx, char *str);
  45. const X509V3_EXT_METHOD v3_pci =
  46. { NID_proxyCertInfo, 0, ASN1_ITEM_ref(PROXY_CERT_INFO_EXTENSION),
  47. 0, 0, 0, 0,
  48. 0, 0,
  49. NULL, NULL,
  50. (X509V3_EXT_I2R)i2r_pci,
  51. (X509V3_EXT_R2I)r2i_pci,
  52. NULL,
  53. };
  54. static int i2r_pci(X509V3_EXT_METHOD *method, PROXY_CERT_INFO_EXTENSION *pci,
  55. BIO *out, int indent)
  56. {
  57. BIO_printf(out, "%*sPath Length Constraint: ", indent, "");
  58. if (pci->pcPathLengthConstraint)
  59. i2a_ASN1_INTEGER(out, pci->pcPathLengthConstraint);
  60. else
  61. BIO_printf(out, "infinite");
  62. BIO_puts(out, "\n");
  63. BIO_printf(out, "%*sPolicy Language: ", indent, "");
  64. i2a_ASN1_OBJECT(out, pci->proxyPolicy->policyLanguage);
  65. BIO_puts(out, "\n");
  66. if (pci->proxyPolicy->policy && pci->proxyPolicy->policy->data)
  67. BIO_printf(out, "%*sPolicy Text: %s\n", indent, "",
  68. pci->proxyPolicy->policy->data);
  69. return 1;
  70. }
  71. static int process_pci_value(CONF_VALUE *val,
  72. ASN1_OBJECT **language, ASN1_INTEGER **pathlen,
  73. ASN1_OCTET_STRING **policy)
  74. {
  75. int free_policy = 0;
  76. if (strcmp(val->name, "language") == 0) {
  77. if (*language) {
  78. X509V3err(X509V3_F_PROCESS_PCI_VALUE,
  79. X509V3_R_POLICY_LANGUAGE_ALREADTY_DEFINED);
  80. X509V3_conf_err(val);
  81. return 0;
  82. }
  83. if (!(*language = OBJ_txt2obj(val->value, 0))) {
  84. X509V3err(X509V3_F_PROCESS_PCI_VALUE,
  85. X509V3_R_INVALID_OBJECT_IDENTIFIER);
  86. X509V3_conf_err(val);
  87. return 0;
  88. }
  89. } else if (strcmp(val->name, "pathlen") == 0) {
  90. if (*pathlen) {
  91. X509V3err(X509V3_F_PROCESS_PCI_VALUE,
  92. X509V3_R_POLICY_PATH_LENGTH_ALREADTY_DEFINED);
  93. X509V3_conf_err(val);
  94. return 0;
  95. }
  96. if (!X509V3_get_value_int(val, pathlen)) {
  97. X509V3err(X509V3_F_PROCESS_PCI_VALUE,
  98. X509V3_R_POLICY_PATH_LENGTH);
  99. X509V3_conf_err(val);
  100. return 0;
  101. }
  102. } else if (strcmp(val->name, "policy") == 0) {
  103. unsigned char *tmp_data = NULL;
  104. long val_len;
  105. if (!*policy) {
  106. *policy = ASN1_OCTET_STRING_new();
  107. if (!*policy) {
  108. X509V3err(X509V3_F_PROCESS_PCI_VALUE, ERR_R_MALLOC_FAILURE);
  109. X509V3_conf_err(val);
  110. return 0;
  111. }
  112. free_policy = 1;
  113. }
  114. if (strncmp(val->value, "hex:", 4) == 0) {
  115. unsigned char *tmp_data2 =
  116. string_to_hex(val->value + 4, &val_len);
  117. if (!tmp_data2) {
  118. X509V3err(X509V3_F_PROCESS_PCI_VALUE,
  119. X509V3_R_ILLEGAL_HEX_DIGIT);
  120. X509V3_conf_err(val);
  121. goto err;
  122. }
  123. tmp_data = OPENSSL_realloc((*policy)->data,
  124. (*policy)->length + val_len + 1);
  125. if (tmp_data) {
  126. (*policy)->data = tmp_data;
  127. memcpy(&(*policy)->data[(*policy)->length],
  128. tmp_data2, val_len);
  129. (*policy)->length += val_len;
  130. (*policy)->data[(*policy)->length] = '\0';
  131. } else {
  132. OPENSSL_free(tmp_data2);
  133. /*
  134. * realloc failure implies the original data space is b0rked
  135. * too!
  136. */
  137. (*policy)->data = NULL;
  138. (*policy)->length = 0;
  139. X509V3err(X509V3_F_PROCESS_PCI_VALUE, ERR_R_MALLOC_FAILURE);
  140. X509V3_conf_err(val);
  141. goto err;
  142. }
  143. OPENSSL_free(tmp_data2);
  144. } else if (strncmp(val->value, "file:", 5) == 0) {
  145. unsigned char buf[2048];
  146. int n;
  147. BIO *b = BIO_new_file(val->value + 5, "r");
  148. if (!b) {
  149. X509V3err(X509V3_F_PROCESS_PCI_VALUE, ERR_R_BIO_LIB);
  150. X509V3_conf_err(val);
  151. goto err;
  152. }
  153. while ((n = BIO_read(b, buf, sizeof(buf))) > 0
  154. || (n == 0 && BIO_should_retry(b))) {
  155. if (!n)
  156. continue;
  157. tmp_data = OPENSSL_realloc((*policy)->data,
  158. (*policy)->length + n + 1);
  159. if (!tmp_data)
  160. break;
  161. (*policy)->data = tmp_data;
  162. memcpy(&(*policy)->data[(*policy)->length], buf, n);
  163. (*policy)->length += n;
  164. (*policy)->data[(*policy)->length] = '\0';
  165. }
  166. BIO_free_all(b);
  167. if (n < 0) {
  168. X509V3err(X509V3_F_PROCESS_PCI_VALUE, ERR_R_BIO_LIB);
  169. X509V3_conf_err(val);
  170. goto err;
  171. }
  172. } else if (strncmp(val->value, "text:", 5) == 0) {
  173. val_len = strlen(val->value + 5);
  174. tmp_data = OPENSSL_realloc((*policy)->data,
  175. (*policy)->length + val_len + 1);
  176. if (tmp_data) {
  177. (*policy)->data = tmp_data;
  178. memcpy(&(*policy)->data[(*policy)->length],
  179. val->value + 5, val_len);
  180. (*policy)->length += val_len;
  181. (*policy)->data[(*policy)->length] = '\0';
  182. } else {
  183. /*
  184. * realloc failure implies the original data space is b0rked
  185. * too!
  186. */
  187. (*policy)->data = NULL;
  188. (*policy)->length = 0;
  189. X509V3err(X509V3_F_PROCESS_PCI_VALUE, ERR_R_MALLOC_FAILURE);
  190. X509V3_conf_err(val);
  191. goto err;
  192. }
  193. } else {
  194. X509V3err(X509V3_F_PROCESS_PCI_VALUE,
  195. X509V3_R_INCORRECT_POLICY_SYNTAX_TAG);
  196. X509V3_conf_err(val);
  197. goto err;
  198. }
  199. if (!tmp_data) {
  200. X509V3err(X509V3_F_PROCESS_PCI_VALUE, ERR_R_MALLOC_FAILURE);
  201. X509V3_conf_err(val);
  202. goto err;
  203. }
  204. }
  205. return 1;
  206. err:
  207. if (free_policy) {
  208. ASN1_OCTET_STRING_free(*policy);
  209. *policy = NULL;
  210. }
  211. return 0;
  212. }
  213. static PROXY_CERT_INFO_EXTENSION *r2i_pci(X509V3_EXT_METHOD *method,
  214. X509V3_CTX *ctx, char *value)
  215. {
  216. PROXY_CERT_INFO_EXTENSION *pci = NULL;
  217. STACK_OF(CONF_VALUE) *vals;
  218. ASN1_OBJECT *language = NULL;
  219. ASN1_INTEGER *pathlen = NULL;
  220. ASN1_OCTET_STRING *policy = NULL;
  221. int i, j;
  222. vals = X509V3_parse_list(value);
  223. for (i = 0; i < sk_CONF_VALUE_num(vals); i++) {
  224. CONF_VALUE *cnf = sk_CONF_VALUE_value(vals, i);
  225. if (!cnf->name || (*cnf->name != '@' && !cnf->value)) {
  226. X509V3err(X509V3_F_R2I_PCI,
  227. X509V3_R_INVALID_PROXY_POLICY_SETTING);
  228. X509V3_conf_err(cnf);
  229. goto err;
  230. }
  231. if (*cnf->name == '@') {
  232. STACK_OF(CONF_VALUE) *sect;
  233. int success_p = 1;
  234. sect = X509V3_get_section(ctx, cnf->name + 1);
  235. if (!sect) {
  236. X509V3err(X509V3_F_R2I_PCI, X509V3_R_INVALID_SECTION);
  237. X509V3_conf_err(cnf);
  238. goto err;
  239. }
  240. for (j = 0; success_p && j < sk_CONF_VALUE_num(sect); j++) {
  241. success_p =
  242. process_pci_value(sk_CONF_VALUE_value(sect, j),
  243. &language, &pathlen, &policy);
  244. }
  245. X509V3_section_free(ctx, sect);
  246. if (!success_p)
  247. goto err;
  248. } else {
  249. if (!process_pci_value(cnf, &language, &pathlen, &policy)) {
  250. X509V3_conf_err(cnf);
  251. goto err;
  252. }
  253. }
  254. }
  255. /* Language is mandatory */
  256. if (!language) {
  257. X509V3err(X509V3_F_R2I_PCI,
  258. X509V3_R_NO_PROXY_CERT_POLICY_LANGUAGE_DEFINED);
  259. goto err;
  260. }
  261. i = OBJ_obj2nid(language);
  262. if ((i == NID_Independent || i == NID_id_ppl_inheritAll) && policy) {
  263. X509V3err(X509V3_F_R2I_PCI,
  264. X509V3_R_POLICY_WHEN_PROXY_LANGUAGE_REQUIRES_NO_POLICY);
  265. goto err;
  266. }
  267. pci = PROXY_CERT_INFO_EXTENSION_new();
  268. if (!pci) {
  269. X509V3err(X509V3_F_R2I_PCI, ERR_R_MALLOC_FAILURE);
  270. goto err;
  271. }
  272. pci->proxyPolicy->policyLanguage = language;
  273. language = NULL;
  274. pci->proxyPolicy->policy = policy;
  275. policy = NULL;
  276. pci->pcPathLengthConstraint = pathlen;
  277. pathlen = NULL;
  278. goto end;
  279. err:
  280. if (language) {
  281. ASN1_OBJECT_free(language);
  282. language = NULL;
  283. }
  284. if (pathlen) {
  285. ASN1_INTEGER_free(pathlen);
  286. pathlen = NULL;
  287. }
  288. if (policy) {
  289. ASN1_OCTET_STRING_free(policy);
  290. policy = NULL;
  291. }
  292. if (pci) {
  293. PROXY_CERT_INFO_EXTENSION_free(pci);
  294. pci = NULL;
  295. }
  296. end:
  297. sk_CONF_VALUE_pop_free(vals, X509V3_conf_free);
  298. return pci;
  299. }