Não pode escolher mais do que 25 tópicos Os tópicos devem começar com uma letra ou um número, podem incluir traços ('-') e podem ter até 35 caracteres.
 
 
 
 
 
 

382 linhas
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 <string.h>
  57. #include <openssl/asn1.h>
  58. #include <openssl/err.h>
  59. #include <openssl/evp.h>
  60. #include <openssl/obj.h>
  61. #include <openssl/stack.h>
  62. #include <openssl/x509.h>
  63. int X509_NAME_get_text_by_NID(X509_NAME *name, int nid, char *buf, int len)
  64. {
  65. const ASN1_OBJECT *obj;
  66. obj=OBJ_nid2obj(nid);
  67. if (obj == NULL) return(-1);
  68. return(X509_NAME_get_text_by_OBJ(name,obj,buf,len));
  69. }
  70. int X509_NAME_get_text_by_OBJ(X509_NAME *name, const ASN1_OBJECT *obj, char *buf,
  71. int len)
  72. {
  73. int i;
  74. ASN1_STRING *data;
  75. i=X509_NAME_get_index_by_OBJ(name,obj,-1);
  76. if (i < 0) return(-1);
  77. data=X509_NAME_ENTRY_get_data(X509_NAME_get_entry(name,i));
  78. i=(data->length > (len-1))?(len-1):data->length;
  79. if (buf == NULL) return(data->length);
  80. memcpy(buf,data->data,i);
  81. buf[i]='\0';
  82. return(i);
  83. }
  84. int X509_NAME_entry_count(X509_NAME *name)
  85. {
  86. if (name == NULL) return(0);
  87. return(sk_X509_NAME_ENTRY_num(name->entries));
  88. }
  89. int X509_NAME_get_index_by_NID(X509_NAME *name, int nid, int lastpos)
  90. {
  91. const ASN1_OBJECT *obj;
  92. obj=OBJ_nid2obj(nid);
  93. if (obj == NULL) return(-2);
  94. return(X509_NAME_get_index_by_OBJ(name,obj,lastpos));
  95. }
  96. /* NOTE: you should be passsing -1, not 0 as lastpos */
  97. int X509_NAME_get_index_by_OBJ(X509_NAME *name, const ASN1_OBJECT *obj,
  98. int lastpos)
  99. {
  100. int n;
  101. X509_NAME_ENTRY *ne;
  102. STACK_OF(X509_NAME_ENTRY) *sk;
  103. if (name == NULL) return(-1);
  104. if (lastpos < 0)
  105. lastpos= -1;
  106. sk=name->entries;
  107. n=sk_X509_NAME_ENTRY_num(sk);
  108. for (lastpos++; lastpos < n; lastpos++)
  109. {
  110. ne=sk_X509_NAME_ENTRY_value(sk,lastpos);
  111. if (OBJ_cmp(ne->object,obj) == 0)
  112. return(lastpos);
  113. }
  114. return(-1);
  115. }
  116. X509_NAME_ENTRY *X509_NAME_get_entry(X509_NAME *name, int loc)
  117. {
  118. if(name == NULL || loc < 0 || sk_X509_NAME_ENTRY_num(name->entries) <= (size_t) loc)
  119. return(NULL);
  120. else
  121. return(sk_X509_NAME_ENTRY_value(name->entries,loc));
  122. }
  123. X509_NAME_ENTRY *X509_NAME_delete_entry(X509_NAME *name, int loc)
  124. {
  125. X509_NAME_ENTRY *ret;
  126. int i,n,set_prev,set_next;
  127. STACK_OF(X509_NAME_ENTRY) *sk;
  128. if (name == NULL || loc < 0 || sk_X509_NAME_ENTRY_num(name->entries) <= (size_t) loc)
  129. return(NULL);
  130. sk=name->entries;
  131. ret=sk_X509_NAME_ENTRY_delete(sk,loc);
  132. n=sk_X509_NAME_ENTRY_num(sk);
  133. name->modified=1;
  134. if (loc == n) return(ret);
  135. /* else we need to fixup the set field */
  136. if (loc != 0)
  137. set_prev=(sk_X509_NAME_ENTRY_value(sk,loc-1))->set;
  138. else
  139. set_prev=ret->set-1;
  140. set_next=sk_X509_NAME_ENTRY_value(sk,loc)->set;
  141. /* set_prev is the previous set
  142. * set is the current set
  143. * set_next is the following
  144. * prev 1 1 1 1 1 1 1 1
  145. * set 1 1 2 2
  146. * next 1 1 2 2 2 2 3 2
  147. * so basically only if prev and next differ by 2, then
  148. * re-number down by 1 */
  149. if (set_prev+1 < set_next)
  150. for (i=loc; i<n; i++)
  151. sk_X509_NAME_ENTRY_value(sk,i)->set--;
  152. return(ret);
  153. }
  154. int X509_NAME_add_entry_by_OBJ(X509_NAME *name, ASN1_OBJECT *obj, int type,
  155. unsigned char *bytes, int len, int loc, int set)
  156. {
  157. X509_NAME_ENTRY *ne;
  158. int ret;
  159. ne = X509_NAME_ENTRY_create_by_OBJ(NULL, obj, type, bytes, len);
  160. if(!ne) return 0;
  161. ret = X509_NAME_add_entry(name, ne, loc, set);
  162. X509_NAME_ENTRY_free(ne);
  163. return ret;
  164. }
  165. int X509_NAME_add_entry_by_NID(X509_NAME *name, int nid, int type,
  166. unsigned char *bytes, int len, int loc, int set)
  167. {
  168. X509_NAME_ENTRY *ne;
  169. int ret;
  170. ne = X509_NAME_ENTRY_create_by_NID(NULL, nid, type, bytes, len);
  171. if(!ne) return 0;
  172. ret = X509_NAME_add_entry(name, ne, loc, set);
  173. X509_NAME_ENTRY_free(ne);
  174. return ret;
  175. }
  176. int X509_NAME_add_entry_by_txt(X509_NAME *name, const char *field, int type,
  177. const unsigned char *bytes, int len, int loc, int set)
  178. {
  179. X509_NAME_ENTRY *ne;
  180. int ret;
  181. ne = X509_NAME_ENTRY_create_by_txt(NULL, field, type, bytes, len);
  182. if(!ne) return 0;
  183. ret = X509_NAME_add_entry(name, ne, loc, set);
  184. X509_NAME_ENTRY_free(ne);
  185. return ret;
  186. }
  187. /* if set is -1, append to previous set, 0 'a new one', and 1,
  188. * prepend to the guy we are about to stomp on. */
  189. int X509_NAME_add_entry(X509_NAME *name, X509_NAME_ENTRY *ne, int loc,
  190. int set)
  191. {
  192. X509_NAME_ENTRY *new_name=NULL;
  193. int n,i,inc;
  194. STACK_OF(X509_NAME_ENTRY) *sk;
  195. if (name == NULL) return(0);
  196. sk=name->entries;
  197. n=sk_X509_NAME_ENTRY_num(sk);
  198. if (loc > n) loc=n;
  199. else if (loc < 0) loc=n;
  200. name->modified=1;
  201. if (set == -1)
  202. {
  203. if (loc == 0)
  204. {
  205. set=0;
  206. inc=1;
  207. }
  208. else
  209. {
  210. set=sk_X509_NAME_ENTRY_value(sk,loc-1)->set;
  211. inc=0;
  212. }
  213. }
  214. else /* if (set >= 0) */
  215. {
  216. if (loc >= n)
  217. {
  218. if (loc != 0)
  219. set=sk_X509_NAME_ENTRY_value(sk,loc-1)->set+1;
  220. else
  221. set=0;
  222. }
  223. else
  224. set=sk_X509_NAME_ENTRY_value(sk,loc)->set;
  225. inc=(set == 0)?1:0;
  226. }
  227. if ((new_name=X509_NAME_ENTRY_dup(ne)) == NULL)
  228. goto err;
  229. new_name->set=set;
  230. if (!sk_X509_NAME_ENTRY_insert(sk,new_name,loc))
  231. {
  232. OPENSSL_PUT_ERROR(X509, X509_NAME_add_entry, ERR_R_MALLOC_FAILURE);
  233. goto err;
  234. }
  235. if (inc)
  236. {
  237. n=sk_X509_NAME_ENTRY_num(sk);
  238. for (i=loc+1; i<n; i++)
  239. sk_X509_NAME_ENTRY_value(sk,i-1)->set+=1;
  240. }
  241. return(1);
  242. err:
  243. if (new_name != NULL)
  244. X509_NAME_ENTRY_free(new_name);
  245. return(0);
  246. }
  247. X509_NAME_ENTRY *X509_NAME_ENTRY_create_by_txt(X509_NAME_ENTRY **ne,
  248. const char *field, int type, const unsigned char *bytes, int len)
  249. {
  250. ASN1_OBJECT *obj;
  251. X509_NAME_ENTRY *nentry;
  252. obj=OBJ_txt2obj(field, 0);
  253. if (obj == NULL)
  254. {
  255. OPENSSL_PUT_ERROR(X509, X509_NAME_ENTRY_create_by_txt, X509_R_INVALID_FIELD_NAME);
  256. ERR_add_error_data(2, "name=", field);
  257. return(NULL);
  258. }
  259. nentry = X509_NAME_ENTRY_create_by_OBJ(ne,obj,type,bytes,len);
  260. ASN1_OBJECT_free(obj);
  261. return nentry;
  262. }
  263. X509_NAME_ENTRY *X509_NAME_ENTRY_create_by_NID(X509_NAME_ENTRY **ne, int nid,
  264. int type, unsigned char *bytes, int len)
  265. {
  266. const ASN1_OBJECT *obj;
  267. X509_NAME_ENTRY *nentry;
  268. obj=OBJ_nid2obj(nid);
  269. if (obj == NULL)
  270. {
  271. OPENSSL_PUT_ERROR(X509, X509_NAME_ENTRY_create_by_NID, X509_R_UNKNOWN_NID);
  272. return(NULL);
  273. }
  274. nentry = X509_NAME_ENTRY_create_by_OBJ(ne,obj,type,bytes,len);
  275. /* TODO(fork): remove this? */
  276. /* ASN1_OBJECT_free(obj); */
  277. return nentry;
  278. }
  279. X509_NAME_ENTRY *X509_NAME_ENTRY_create_by_OBJ(X509_NAME_ENTRY **ne,
  280. const ASN1_OBJECT *obj, int type, const unsigned char *bytes, int len)
  281. {
  282. X509_NAME_ENTRY *ret;
  283. if ((ne == NULL) || (*ne == NULL))
  284. {
  285. if ((ret=X509_NAME_ENTRY_new()) == NULL)
  286. return(NULL);
  287. }
  288. else
  289. ret= *ne;
  290. if (!X509_NAME_ENTRY_set_object(ret,obj))
  291. goto err;
  292. if (!X509_NAME_ENTRY_set_data(ret,type,bytes,len))
  293. goto err;
  294. if ((ne != NULL) && (*ne == NULL)) *ne=ret;
  295. return(ret);
  296. err:
  297. if ((ne == NULL) || (ret != *ne))
  298. X509_NAME_ENTRY_free(ret);
  299. return(NULL);
  300. }
  301. int X509_NAME_ENTRY_set_object(X509_NAME_ENTRY *ne, const ASN1_OBJECT *obj)
  302. {
  303. if ((ne == NULL) || (obj == NULL))
  304. {
  305. OPENSSL_PUT_ERROR(X509, X509_NAME_ENTRY_set_object, ERR_R_PASSED_NULL_PARAMETER);
  306. return(0);
  307. }
  308. ASN1_OBJECT_free(ne->object);
  309. ne->object=OBJ_dup(obj);
  310. return((ne->object == NULL)?0:1);
  311. }
  312. int X509_NAME_ENTRY_set_data(X509_NAME_ENTRY *ne, int type,
  313. const unsigned char *bytes, int len)
  314. {
  315. int i;
  316. if ((ne == NULL) || ((bytes == NULL) && (len != 0))) return(0);
  317. if((type > 0) && (type & MBSTRING_FLAG))
  318. return ASN1_STRING_set_by_NID(&ne->value, bytes,
  319. len, type,
  320. OBJ_obj2nid(ne->object)) ? 1 : 0;
  321. if (len < 0) len=strlen((const char *)bytes);
  322. i=ASN1_STRING_set(ne->value,bytes,len);
  323. if (!i) return(0);
  324. if (type != V_ASN1_UNDEF)
  325. {
  326. if (type == V_ASN1_APP_CHOOSE)
  327. ne->value->type=ASN1_PRINTABLE_type(bytes,len);
  328. else
  329. ne->value->type=type;
  330. }
  331. return(1);
  332. }
  333. ASN1_OBJECT *X509_NAME_ENTRY_get_object(X509_NAME_ENTRY *ne)
  334. {
  335. if (ne == NULL) return(NULL);
  336. return(ne->object);
  337. }
  338. ASN1_STRING *X509_NAME_ENTRY_get_data(X509_NAME_ENTRY *ne)
  339. {
  340. if (ne == NULL) return(NULL);
  341. return(ne->value);
  342. }