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.
 
 
 
 
 
 

380 lines
11 KiB

  1. /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
  2. * All rights reserved.
  3. *
  4. * This package is an SSL implementation written
  5. * by Eric Young (eay@cryptsoft.com).
  6. * The implementation was written so as to conform with Netscapes SSL.
  7. *
  8. * This library is free for commercial and non-commercial use as long as
  9. * the following conditions are aheared to. The following conditions
  10. * apply to all code found in this distribution, be it the RC4, RSA,
  11. * lhash, DES, etc., code; not just the SSL code. The SSL documentation
  12. * included with this distribution is covered by the same copyright terms
  13. * except that the holder is Tim Hudson (tjh@cryptsoft.com).
  14. *
  15. * Copyright remains Eric Young's, and as such any Copyright notices in
  16. * the code are not to be removed.
  17. * If this package is used in a product, Eric Young should be given attribution
  18. * as the author of the parts of the library used.
  19. * This can be in the form of a textual message at program startup or
  20. * in documentation (online or textual) provided with the package.
  21. *
  22. * Redistribution and use in source and binary forms, with or without
  23. * modification, are permitted provided that the following conditions
  24. * are met:
  25. * 1. Redistributions of source code must retain the copyright
  26. * notice, this list of conditions and the following disclaimer.
  27. * 2. Redistributions in binary form must reproduce the above copyright
  28. * notice, this list of conditions and the following disclaimer in the
  29. * documentation and/or other materials provided with the distribution.
  30. * 3. All advertising materials mentioning features or use of this software
  31. * must display the following acknowledgement:
  32. * "This product includes cryptographic software written by
  33. * Eric Young (eay@cryptsoft.com)"
  34. * The word 'cryptographic' can be left out if the rouines from the library
  35. * being used are not cryptographic related :-).
  36. * 4. If you include any Windows specific code (or a derivative thereof) from
  37. * the apps directory (application code) you must include an acknowledgement:
  38. * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
  39. *
  40. * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
  41. * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  42. * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  43. * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
  44. * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  45. * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
  46. * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  47. * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  48. * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  49. * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  50. * SUCH DAMAGE.
  51. *
  52. * The licence and distribution terms for any publically available version or
  53. * derivative of this code cannot be changed. i.e. this code cannot simply be
  54. * copied and put under another distribution licence
  55. * [including the GNU Public Licence.] */
  56. #include <openssl/asn1.h>
  57. #include <openssl/err.h>
  58. #include <openssl/evp.h>
  59. #include <openssl/obj.h>
  60. #include <openssl/stack.h>
  61. #include <openssl/x509.h>
  62. int X509_NAME_get_text_by_NID(X509_NAME *name, int nid, char *buf, int len)
  63. {
  64. const ASN1_OBJECT *obj;
  65. obj=OBJ_nid2obj(nid);
  66. if (obj == NULL) return(-1);
  67. return(X509_NAME_get_text_by_OBJ(name,obj,buf,len));
  68. }
  69. int X509_NAME_get_text_by_OBJ(X509_NAME *name, const ASN1_OBJECT *obj, char *buf,
  70. int len)
  71. {
  72. int i;
  73. ASN1_STRING *data;
  74. i=X509_NAME_get_index_by_OBJ(name,obj,-1);
  75. if (i < 0) return(-1);
  76. data=X509_NAME_ENTRY_get_data(X509_NAME_get_entry(name,i));
  77. i=(data->length > (len-1))?(len-1):data->length;
  78. if (buf == NULL) return(data->length);
  79. memcpy(buf,data->data,i);
  80. buf[i]='\0';
  81. return(i);
  82. }
  83. int X509_NAME_entry_count(X509_NAME *name)
  84. {
  85. if (name == NULL) return(0);
  86. return(sk_X509_NAME_ENTRY_num(name->entries));
  87. }
  88. int X509_NAME_get_index_by_NID(X509_NAME *name, int nid, int lastpos)
  89. {
  90. const ASN1_OBJECT *obj;
  91. obj=OBJ_nid2obj(nid);
  92. if (obj == NULL) return(-2);
  93. return(X509_NAME_get_index_by_OBJ(name,obj,lastpos));
  94. }
  95. /* NOTE: you should be passsing -1, not 0 as lastpos */
  96. int X509_NAME_get_index_by_OBJ(X509_NAME *name, const ASN1_OBJECT *obj,
  97. int lastpos)
  98. {
  99. int n;
  100. X509_NAME_ENTRY *ne;
  101. STACK_OF(X509_NAME_ENTRY) *sk;
  102. if (name == NULL) return(-1);
  103. if (lastpos < 0)
  104. lastpos= -1;
  105. sk=name->entries;
  106. n=sk_X509_NAME_ENTRY_num(sk);
  107. for (lastpos++; lastpos < n; lastpos++)
  108. {
  109. ne=sk_X509_NAME_ENTRY_value(sk,lastpos);
  110. if (OBJ_cmp(ne->object,obj) == 0)
  111. return(lastpos);
  112. }
  113. return(-1);
  114. }
  115. X509_NAME_ENTRY *X509_NAME_get_entry(X509_NAME *name, int loc)
  116. {
  117. if(name == NULL || loc < 0 || sk_X509_NAME_ENTRY_num(name->entries) <= (size_t) loc)
  118. return(NULL);
  119. else
  120. return(sk_X509_NAME_ENTRY_value(name->entries,loc));
  121. }
  122. X509_NAME_ENTRY *X509_NAME_delete_entry(X509_NAME *name, int loc)
  123. {
  124. X509_NAME_ENTRY *ret;
  125. int i,n,set_prev,set_next;
  126. STACK_OF(X509_NAME_ENTRY) *sk;
  127. if (name == NULL || loc < 0 || sk_X509_NAME_ENTRY_num(name->entries) <= (size_t) loc)
  128. return(NULL);
  129. sk=name->entries;
  130. ret=sk_X509_NAME_ENTRY_delete(sk,loc);
  131. n=sk_X509_NAME_ENTRY_num(sk);
  132. name->modified=1;
  133. if (loc == n) return(ret);
  134. /* else we need to fixup the set field */
  135. if (loc != 0)
  136. set_prev=(sk_X509_NAME_ENTRY_value(sk,loc-1))->set;
  137. else
  138. set_prev=ret->set-1;
  139. set_next=sk_X509_NAME_ENTRY_value(sk,loc)->set;
  140. /* set_prev is the previous set
  141. * set is the current set
  142. * set_next is the following
  143. * prev 1 1 1 1 1 1 1 1
  144. * set 1 1 2 2
  145. * next 1 1 2 2 2 2 3 2
  146. * so basically only if prev and next differ by 2, then
  147. * re-number down by 1 */
  148. if (set_prev+1 < set_next)
  149. for (i=loc; i<n; i++)
  150. sk_X509_NAME_ENTRY_value(sk,i)->set--;
  151. return(ret);
  152. }
  153. int X509_NAME_add_entry_by_OBJ(X509_NAME *name, ASN1_OBJECT *obj, int type,
  154. unsigned char *bytes, int len, int loc, int set)
  155. {
  156. X509_NAME_ENTRY *ne;
  157. int ret;
  158. ne = X509_NAME_ENTRY_create_by_OBJ(NULL, obj, type, bytes, len);
  159. if(!ne) return 0;
  160. ret = X509_NAME_add_entry(name, ne, loc, set);
  161. X509_NAME_ENTRY_free(ne);
  162. return ret;
  163. }
  164. int X509_NAME_add_entry_by_NID(X509_NAME *name, int nid, int type,
  165. unsigned char *bytes, int len, int loc, int set)
  166. {
  167. X509_NAME_ENTRY *ne;
  168. int ret;
  169. ne = X509_NAME_ENTRY_create_by_NID(NULL, nid, type, bytes, len);
  170. if(!ne) return 0;
  171. ret = X509_NAME_add_entry(name, ne, loc, set);
  172. X509_NAME_ENTRY_free(ne);
  173. return ret;
  174. }
  175. int X509_NAME_add_entry_by_txt(X509_NAME *name, const char *field, int type,
  176. const unsigned char *bytes, int len, int loc, int set)
  177. {
  178. X509_NAME_ENTRY *ne;
  179. int ret;
  180. ne = X509_NAME_ENTRY_create_by_txt(NULL, field, type, bytes, len);
  181. if(!ne) return 0;
  182. ret = X509_NAME_add_entry(name, ne, loc, set);
  183. X509_NAME_ENTRY_free(ne);
  184. return ret;
  185. }
  186. /* if set is -1, append to previous set, 0 'a new one', and 1,
  187. * prepend to the guy we are about to stomp on. */
  188. int X509_NAME_add_entry(X509_NAME *name, X509_NAME_ENTRY *ne, int loc,
  189. int set)
  190. {
  191. X509_NAME_ENTRY *new_name=NULL;
  192. int n,i,inc;
  193. STACK_OF(X509_NAME_ENTRY) *sk;
  194. if (name == NULL) return(0);
  195. sk=name->entries;
  196. n=sk_X509_NAME_ENTRY_num(sk);
  197. if (loc > n) loc=n;
  198. else if (loc < 0) loc=n;
  199. name->modified=1;
  200. if (set == -1)
  201. {
  202. if (loc == 0)
  203. {
  204. set=0;
  205. inc=1;
  206. }
  207. else
  208. {
  209. set=sk_X509_NAME_ENTRY_value(sk,loc-1)->set;
  210. inc=0;
  211. }
  212. }
  213. else /* if (set >= 0) */
  214. {
  215. if (loc >= n)
  216. {
  217. if (loc != 0)
  218. set=sk_X509_NAME_ENTRY_value(sk,loc-1)->set+1;
  219. else
  220. set=0;
  221. }
  222. else
  223. set=sk_X509_NAME_ENTRY_value(sk,loc)->set;
  224. inc=(set == 0)?1:0;
  225. }
  226. if ((new_name=X509_NAME_ENTRY_dup(ne)) == NULL)
  227. goto err;
  228. new_name->set=set;
  229. if (!sk_X509_NAME_ENTRY_insert(sk,new_name,loc))
  230. {
  231. OPENSSL_PUT_ERROR(X509, X509_NAME_add_entry, ERR_R_MALLOC_FAILURE);
  232. goto err;
  233. }
  234. if (inc)
  235. {
  236. n=sk_X509_NAME_ENTRY_num(sk);
  237. for (i=loc+1; i<n; i++)
  238. sk_X509_NAME_ENTRY_value(sk,i-1)->set+=1;
  239. }
  240. return(1);
  241. err:
  242. if (new_name != NULL)
  243. X509_NAME_ENTRY_free(new_name);
  244. return(0);
  245. }
  246. X509_NAME_ENTRY *X509_NAME_ENTRY_create_by_txt(X509_NAME_ENTRY **ne,
  247. const char *field, int type, const unsigned char *bytes, int len)
  248. {
  249. ASN1_OBJECT *obj;
  250. X509_NAME_ENTRY *nentry;
  251. obj=OBJ_txt2obj(field, 0);
  252. if (obj == NULL)
  253. {
  254. OPENSSL_PUT_ERROR(X509, X509_NAME_ENTRY_create_by_txt, X509_R_INVALID_FIELD_NAME);
  255. ERR_add_error_data(2, "name=", field);
  256. return(NULL);
  257. }
  258. nentry = X509_NAME_ENTRY_create_by_OBJ(ne,obj,type,bytes,len);
  259. ASN1_OBJECT_free(obj);
  260. return nentry;
  261. }
  262. X509_NAME_ENTRY *X509_NAME_ENTRY_create_by_NID(X509_NAME_ENTRY **ne, int nid,
  263. int type, unsigned char *bytes, int len)
  264. {
  265. const ASN1_OBJECT *obj;
  266. X509_NAME_ENTRY *nentry;
  267. obj=OBJ_nid2obj(nid);
  268. if (obj == NULL)
  269. {
  270. OPENSSL_PUT_ERROR(X509, X509_NAME_ENTRY_create_by_NID, X509_R_UNKNOWN_NID);
  271. return(NULL);
  272. }
  273. nentry = X509_NAME_ENTRY_create_by_OBJ(ne,obj,type,bytes,len);
  274. /* TODO(fork): remove this? */
  275. /* ASN1_OBJECT_free(obj); */
  276. return nentry;
  277. }
  278. X509_NAME_ENTRY *X509_NAME_ENTRY_create_by_OBJ(X509_NAME_ENTRY **ne,
  279. const ASN1_OBJECT *obj, int type, const unsigned char *bytes, int len)
  280. {
  281. X509_NAME_ENTRY *ret;
  282. if ((ne == NULL) || (*ne == NULL))
  283. {
  284. if ((ret=X509_NAME_ENTRY_new()) == NULL)
  285. return(NULL);
  286. }
  287. else
  288. ret= *ne;
  289. if (!X509_NAME_ENTRY_set_object(ret,obj))
  290. goto err;
  291. if (!X509_NAME_ENTRY_set_data(ret,type,bytes,len))
  292. goto err;
  293. if ((ne != NULL) && (*ne == NULL)) *ne=ret;
  294. return(ret);
  295. err:
  296. if ((ne == NULL) || (ret != *ne))
  297. X509_NAME_ENTRY_free(ret);
  298. return(NULL);
  299. }
  300. int X509_NAME_ENTRY_set_object(X509_NAME_ENTRY *ne, const ASN1_OBJECT *obj)
  301. {
  302. if ((ne == NULL) || (obj == NULL))
  303. {
  304. OPENSSL_PUT_ERROR(X509, X509_NAME_ENTRY_set_object, ERR_R_PASSED_NULL_PARAMETER);
  305. return(0);
  306. }
  307. ASN1_OBJECT_free(ne->object);
  308. ne->object=OBJ_dup(obj);
  309. return((ne->object == NULL)?0:1);
  310. }
  311. int X509_NAME_ENTRY_set_data(X509_NAME_ENTRY *ne, int type,
  312. const unsigned char *bytes, int len)
  313. {
  314. int i;
  315. if ((ne == NULL) || ((bytes == NULL) && (len != 0))) return(0);
  316. if((type > 0) && (type & MBSTRING_FLAG))
  317. return ASN1_STRING_set_by_NID(&ne->value, bytes,
  318. len, type,
  319. OBJ_obj2nid(ne->object)) ? 1 : 0;
  320. if (len < 0) len=strlen((const char *)bytes);
  321. i=ASN1_STRING_set(ne->value,bytes,len);
  322. if (!i) return(0);
  323. if (type != V_ASN1_UNDEF)
  324. {
  325. if (type == V_ASN1_APP_CHOOSE)
  326. ne->value->type=ASN1_PRINTABLE_type(bytes,len);
  327. else
  328. ne->value->type=type;
  329. }
  330. return(1);
  331. }
  332. ASN1_OBJECT *X509_NAME_ENTRY_get_object(X509_NAME_ENTRY *ne)
  333. {
  334. if (ne == NULL) return(NULL);
  335. return(ne->object);
  336. }
  337. ASN1_STRING *X509_NAME_ENTRY_get_data(X509_NAME_ENTRY *ne)
  338. {
  339. if (ne == NULL) return(NULL);
  340. return(ne->value);
  341. }