You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

288 lines
9.7 KiB

  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 <string.h>
  38. #include <openssl/conf.h>
  39. #include <openssl/err.h>
  40. #include <openssl/mem.h>
  41. #include <openssl/obj.h>
  42. #include <openssl/x509v3.h>
  43. #include "../internal.h"
  44. static int i2r_pci(X509V3_EXT_METHOD *method, PROXY_CERT_INFO_EXTENSION *ext,
  45. BIO *out, int indent);
  46. static PROXY_CERT_INFO_EXTENSION *r2i_pci(X509V3_EXT_METHOD *method,
  47. X509V3_CTX *ctx, char *str);
  48. const X509V3_EXT_METHOD v3_pci =
  49. { NID_proxyCertInfo, 0, ASN1_ITEM_ref(PROXY_CERT_INFO_EXTENSION),
  50. 0, 0, 0, 0,
  51. 0, 0,
  52. NULL, NULL,
  53. (X509V3_EXT_I2R)i2r_pci,
  54. (X509V3_EXT_R2I)r2i_pci,
  55. NULL,
  56. };
  57. static int i2r_pci(X509V3_EXT_METHOD *method, PROXY_CERT_INFO_EXTENSION *pci,
  58. BIO *out, int indent)
  59. {
  60. BIO_printf(out, "%*sPath Length Constraint: ", indent, "");
  61. if (pci->pcPathLengthConstraint)
  62. i2a_ASN1_INTEGER(out, pci->pcPathLengthConstraint);
  63. else
  64. BIO_printf(out, "infinite");
  65. BIO_puts(out, "\n");
  66. BIO_printf(out, "%*sPolicy Language: ", indent, "");
  67. i2a_ASN1_OBJECT(out, pci->proxyPolicy->policyLanguage);
  68. BIO_puts(out, "\n");
  69. if (pci->proxyPolicy->policy && pci->proxyPolicy->policy->data)
  70. BIO_printf(out, "%*sPolicy Text: %s\n", indent, "",
  71. pci->proxyPolicy->policy->data);
  72. return 1;
  73. }
  74. static int process_pci_value(CONF_VALUE *val,
  75. ASN1_OBJECT **language, ASN1_INTEGER **pathlen,
  76. ASN1_OCTET_STRING **policy)
  77. {
  78. int free_policy = 0;
  79. if (strcmp(val->name, "language") == 0) {
  80. if (*language) {
  81. OPENSSL_PUT_ERROR(X509V3,
  82. X509V3_R_POLICY_LANGUAGE_ALREADY_DEFINED);
  83. X509V3_conf_err(val);
  84. return 0;
  85. }
  86. if (!(*language = OBJ_txt2obj(val->value, 0))) {
  87. OPENSSL_PUT_ERROR(X509V3, X509V3_R_INVALID_OBJECT_IDENTIFIER);
  88. X509V3_conf_err(val);
  89. return 0;
  90. }
  91. } else if (strcmp(val->name, "pathlen") == 0) {
  92. if (*pathlen) {
  93. OPENSSL_PUT_ERROR(X509V3,
  94. X509V3_R_POLICY_PATH_LENGTH_ALREADY_DEFINED);
  95. X509V3_conf_err(val);
  96. return 0;
  97. }
  98. if (!X509V3_get_value_int(val, pathlen)) {
  99. OPENSSL_PUT_ERROR(X509V3, X509V3_R_POLICY_PATH_LENGTH);
  100. X509V3_conf_err(val);
  101. return 0;
  102. }
  103. } else if (strcmp(val->name, "policy") == 0) {
  104. unsigned char *tmp_data = NULL;
  105. long val_len;
  106. if (!*policy) {
  107. *policy = ASN1_OCTET_STRING_new();
  108. if (!*policy) {
  109. OPENSSL_PUT_ERROR(X509V3, ERR_R_MALLOC_FAILURE);
  110. X509V3_conf_err(val);
  111. return 0;
  112. }
  113. free_policy = 1;
  114. }
  115. if (strncmp(val->value, "hex:", 4) == 0) {
  116. unsigned char *tmp_data2 =
  117. string_to_hex(val->value + 4, &val_len);
  118. if (!tmp_data2) {
  119. OPENSSL_PUT_ERROR(X509V3, 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. OPENSSL_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. OPENSSL_PUT_ERROR(X509V3, ERR_R_MALLOC_FAILURE);
  140. X509V3_conf_err(val);
  141. goto err;
  142. }
  143. OPENSSL_free(tmp_data2);
  144. } else if (strncmp(val->value, "text:", 5) == 0) {
  145. val_len = strlen(val->value + 5);
  146. tmp_data = OPENSSL_realloc((*policy)->data,
  147. (*policy)->length + val_len + 1);
  148. if (tmp_data) {
  149. (*policy)->data = tmp_data;
  150. OPENSSL_memcpy(&(*policy)->data[(*policy)->length],
  151. val->value + 5, val_len);
  152. (*policy)->length += val_len;
  153. (*policy)->data[(*policy)->length] = '\0';
  154. } else {
  155. /*
  156. * realloc failure implies the original data space is b0rked
  157. * too!
  158. */
  159. (*policy)->data = NULL;
  160. (*policy)->length = 0;
  161. OPENSSL_PUT_ERROR(X509V3, ERR_R_MALLOC_FAILURE);
  162. X509V3_conf_err(val);
  163. goto err;
  164. }
  165. } else {
  166. OPENSSL_PUT_ERROR(X509V3, X509V3_R_INCORRECT_POLICY_SYNTAX_TAG);
  167. X509V3_conf_err(val);
  168. goto err;
  169. }
  170. if (!tmp_data) {
  171. OPENSSL_PUT_ERROR(X509V3, ERR_R_MALLOC_FAILURE);
  172. X509V3_conf_err(val);
  173. goto err;
  174. }
  175. }
  176. return 1;
  177. err:
  178. if (free_policy) {
  179. ASN1_OCTET_STRING_free(*policy);
  180. *policy = NULL;
  181. }
  182. return 0;
  183. }
  184. static PROXY_CERT_INFO_EXTENSION *r2i_pci(X509V3_EXT_METHOD *method,
  185. X509V3_CTX *ctx, char *value)
  186. {
  187. PROXY_CERT_INFO_EXTENSION *pci = NULL;
  188. STACK_OF(CONF_VALUE) *vals;
  189. ASN1_OBJECT *language = NULL;
  190. ASN1_INTEGER *pathlen = NULL;
  191. ASN1_OCTET_STRING *policy = NULL;
  192. size_t i, j;
  193. int nid;
  194. vals = X509V3_parse_list(value);
  195. for (i = 0; i < sk_CONF_VALUE_num(vals); i++) {
  196. CONF_VALUE *cnf = sk_CONF_VALUE_value(vals, i);
  197. if (!cnf->name || (*cnf->name != '@' && !cnf->value)) {
  198. OPENSSL_PUT_ERROR(X509V3, X509V3_R_INVALID_PROXY_POLICY_SETTING);
  199. X509V3_conf_err(cnf);
  200. goto err;
  201. }
  202. if (*cnf->name == '@') {
  203. STACK_OF(CONF_VALUE) *sect;
  204. int success_p = 1;
  205. sect = X509V3_get_section(ctx, cnf->name + 1);
  206. if (!sect) {
  207. OPENSSL_PUT_ERROR(X509V3, X509V3_R_INVALID_SECTION);
  208. X509V3_conf_err(cnf);
  209. goto err;
  210. }
  211. for (j = 0; success_p && j < sk_CONF_VALUE_num(sect); j++) {
  212. success_p =
  213. process_pci_value(sk_CONF_VALUE_value(sect, j),
  214. &language, &pathlen, &policy);
  215. }
  216. X509V3_section_free(ctx, sect);
  217. if (!success_p)
  218. goto err;
  219. } else {
  220. if (!process_pci_value(cnf, &language, &pathlen, &policy)) {
  221. X509V3_conf_err(cnf);
  222. goto err;
  223. }
  224. }
  225. }
  226. /* Language is mandatory */
  227. if (!language) {
  228. OPENSSL_PUT_ERROR(X509V3,
  229. X509V3_R_NO_PROXY_CERT_POLICY_LANGUAGE_DEFINED);
  230. goto err;
  231. }
  232. nid = OBJ_obj2nid(language);
  233. if ((nid == NID_Independent || nid == NID_id_ppl_inheritAll) && policy) {
  234. OPENSSL_PUT_ERROR(X509V3,
  235. X509V3_R_POLICY_WHEN_PROXY_LANGUAGE_REQUIRES_NO_POLICY);
  236. goto err;
  237. }
  238. pci = PROXY_CERT_INFO_EXTENSION_new();
  239. if (!pci) {
  240. OPENSSL_PUT_ERROR(X509V3, ERR_R_MALLOC_FAILURE);
  241. goto err;
  242. }
  243. pci->proxyPolicy->policyLanguage = language;
  244. language = NULL;
  245. pci->proxyPolicy->policy = policy;
  246. policy = NULL;
  247. pci->pcPathLengthConstraint = pathlen;
  248. pathlen = NULL;
  249. goto end;
  250. err:
  251. if (language) {
  252. ASN1_OBJECT_free(language);
  253. language = NULL;
  254. }
  255. if (pathlen) {
  256. ASN1_INTEGER_free(pathlen);
  257. pathlen = NULL;
  258. }
  259. if (policy) {
  260. ASN1_OCTET_STRING_free(policy);
  261. policy = NULL;
  262. }
  263. if (pci) {
  264. PROXY_CERT_INFO_EXTENSION_free(pci);
  265. pci = NULL;
  266. }
  267. end:
  268. sk_CONF_VALUE_pop_free(vals, X509V3_conf_free);
  269. return pci;
  270. }