openssl.c 9.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342
  1. /* apps/openssl.c */
  2. /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
  3. * All rights reserved.
  4. *
  5. * This package is an SSL implementation written
  6. * by Eric Young (eay@cryptsoft.com).
  7. * The implementation was written so as to conform with Netscapes SSL.
  8. *
  9. * This library is free for commercial and non-commercial use as long as
  10. * the following conditions are aheared to. The following conditions
  11. * apply to all code found in this distribution, be it the RC4, RSA,
  12. * lhash, DES, etc., code; not just the SSL code. The SSL documentation
  13. * included with this distribution is covered by the same copyright terms
  14. * except that the holder is Tim Hudson (tjh@cryptsoft.com).
  15. *
  16. * Copyright remains Eric Young's, and as such any Copyright notices in
  17. * the code are not to be removed.
  18. * If this package is used in a product, Eric Young should be given attribution
  19. * as the author of the parts of the library used.
  20. * This can be in the form of a textual message at program startup or
  21. * in documentation (online or textual) provided with the package.
  22. *
  23. * Redistribution and use in source and binary forms, with or without
  24. * modification, are permitted provided that the following conditions
  25. * are met:
  26. * 1. Redistributions of source code must retain the copyright
  27. * notice, this list of conditions and the following disclaimer.
  28. * 2. Redistributions in binary form must reproduce the above copyright
  29. * notice, this list of conditions and the following disclaimer in the
  30. * documentation and/or other materials provided with the distribution.
  31. * 3. All advertising materials mentioning features or use of this software
  32. * must display the following acknowledgement:
  33. * "This product includes cryptographic software written by
  34. * Eric Young (eay@cryptsoft.com)"
  35. * The word 'cryptographic' can be left out if the rouines from the library
  36. * being used are not cryptographic related :-).
  37. * 4. If you include any Windows specific code (or a derivative thereof) from
  38. * the apps directory (application code) you must include an acknowledgement:
  39. * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
  40. *
  41. * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
  42. * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  43. * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  44. * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
  45. * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  46. * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
  47. * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  48. * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  49. * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  50. * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  51. * SUCH DAMAGE.
  52. *
  53. * The licence and distribution terms for any publically available version or
  54. * derivative of this code cannot be changed. i.e. this code cannot simply be
  55. * copied and put under another distribution licence
  56. * [including the GNU Public Licence.]
  57. */
  58. #include <stdio.h>
  59. #include <string.h>
  60. #include <stdlib.h>
  61. #include <openssl/bio.h>
  62. #include <openssl/crypto.h>
  63. #include <openssl/lhash.h>
  64. #include <openssl/conf.h>
  65. #include <openssl/x509.h>
  66. #include <openssl/pem.h>
  67. #include <openssl/ssl.h>
  68. #define USE_SOCKETS /* needed for the _O_BINARY defs in the MS world */
  69. #define OPENSSL_C /* tells apps.h to use complete apps_startup() */
  70. #include "apps.h"
  71. #include "progs.h"
  72. #include "s_apps.h"
  73. #include <openssl/err.h>
  74. static unsigned long MS_CALLBACK hash(FUNCTION *a);
  75. static int MS_CALLBACK cmp(FUNCTION *a,FUNCTION *b);
  76. static LHASH *prog_init(void );
  77. static int do_cmd(LHASH *prog,int argc,char *argv[]);
  78. LHASH *config=NULL;
  79. char *default_config_file=NULL;
  80. /* Make sure there is only one when MONOLITH is defined */
  81. #ifdef MONOLITH
  82. BIO *bio_err=NULL;
  83. #endif
  84. int main(int Argc, char *Argv[])
  85. {
  86. ARGS arg;
  87. #define PROG_NAME_SIZE 16
  88. char pname[PROG_NAME_SIZE];
  89. FUNCTION f,*fp;
  90. MS_STATIC char *prompt,buf[1024],config_name[256];
  91. int n,i,ret=0;
  92. int argc;
  93. char **argv,*p;
  94. LHASH *prog=NULL;
  95. long errline;
  96. arg.data=NULL;
  97. arg.count=0;
  98. CRYPTO_mem_ctrl(CRYPTO_MEM_CHECK_ON);
  99. apps_startup();
  100. if (bio_err == NULL)
  101. if ((bio_err=BIO_new(BIO_s_file())) != NULL)
  102. BIO_set_fp(bio_err,stderr,BIO_NOCLOSE|BIO_FP_TEXT);
  103. ERR_load_crypto_strings();
  104. /* Lets load up our environment a little */
  105. p=getenv("OPENSSL_CONF");
  106. if (p == NULL)
  107. p=getenv("SSLEAY_CONF");
  108. if (p == NULL)
  109. {
  110. strcpy(config_name,X509_get_default_cert_area());
  111. #ifndef VMS
  112. strcat(config_name,"/");
  113. #endif
  114. strcat(config_name,OPENSSL_CONF);
  115. p=config_name;
  116. }
  117. default_config_file=p;
  118. config=CONF_load(config,p,&errline);
  119. if (config == NULL) ERR_clear_error();
  120. prog=prog_init();
  121. /* first check the program name */
  122. program_name(Argv[0],pname,PROG_NAME_SIZE);
  123. f.name=pname;
  124. fp=(FUNCTION *)lh_retrieve(prog,&f);
  125. if (fp != NULL)
  126. {
  127. Argv[0]=pname;
  128. ret=fp->func(Argc,Argv);
  129. goto end;
  130. }
  131. /* ok, now check that there are not arguments, if there are,
  132. * run with them, shifting the ssleay off the front */
  133. if (Argc != 1)
  134. {
  135. Argc--;
  136. Argv++;
  137. ret=do_cmd(prog,Argc,Argv);
  138. if (ret < 0) ret=0;
  139. goto end;
  140. }
  141. /* ok, lets enter the old 'OpenSSL>' mode */
  142. for (;;)
  143. {
  144. ret=0;
  145. p=buf;
  146. n=1024;
  147. i=0;
  148. for (;;)
  149. {
  150. p[0]='\0';
  151. if (i++)
  152. prompt=">";
  153. else prompt="OpenSSL> ";
  154. fputs(prompt,stdout);
  155. fflush(stdout);
  156. fgets(p,n,stdin);
  157. if (p[0] == '\0') goto end;
  158. i=strlen(p);
  159. if (i <= 1) break;
  160. if (p[i-2] != '\\') break;
  161. i-=2;
  162. p+=i;
  163. n-=i;
  164. }
  165. if (!chopup_args(&arg,buf,&argc,&argv)) break;
  166. ret=do_cmd(prog,argc,argv);
  167. if (ret < 0)
  168. {
  169. ret=0;
  170. goto end;
  171. }
  172. if (ret != 0)
  173. BIO_printf(bio_err,"error in %s\n",argv[0]);
  174. (void)BIO_flush(bio_err);
  175. }
  176. BIO_printf(bio_err,"bad exit\n");
  177. ret=1;
  178. end:
  179. if (config != NULL)
  180. {
  181. CONF_free(config);
  182. config=NULL;
  183. }
  184. if (prog != NULL) lh_free(prog);
  185. if (arg.data != NULL) Free(arg.data);
  186. ERR_remove_state(0);
  187. EVP_cleanup();
  188. ERR_free_strings();
  189. CRYPTO_mem_leaks(bio_err);
  190. if (bio_err != NULL)
  191. {
  192. BIO_free(bio_err);
  193. bio_err=NULL;
  194. }
  195. EXIT(ret);
  196. }
  197. #define LIST_STANDARD_COMMANDS "list-standard-commands"
  198. #define LIST_MESSAGE_DIGEST_COMMANDS "list-message-digest-commands"
  199. #define LIST_CIPHER_COMMANDS "list-cipher-commands"
  200. static int do_cmd(LHASH *prog, int argc, char *argv[])
  201. {
  202. FUNCTION f,*fp;
  203. int i,ret=1,tp,nl;
  204. if ((argc <= 0) || (argv[0] == NULL))
  205. { ret=0; goto end; }
  206. f.name=argv[0];
  207. fp=(FUNCTION *)lh_retrieve(prog,&f);
  208. if (fp != NULL)
  209. {
  210. ret=fp->func(argc,argv);
  211. }
  212. else if ((strcmp(argv[0],"quit") == 0) ||
  213. (strcmp(argv[0],"q") == 0) ||
  214. (strcmp(argv[0],"exit") == 0) ||
  215. (strcmp(argv[0],"bye") == 0))
  216. {
  217. ret= -1;
  218. goto end;
  219. }
  220. else if ((strcmp(argv[0],LIST_STANDARD_COMMANDS) == 0) ||
  221. (strcmp(argv[0],LIST_MESSAGE_DIGEST_COMMANDS) == 0) ||
  222. (strcmp(argv[0],LIST_CIPHER_COMMANDS) == 0))
  223. {
  224. int list_type;
  225. BIO *bio_stdout;
  226. if (strcmp(argv[0],LIST_STANDARD_COMMANDS) == 0)
  227. list_type = FUNC_TYPE_GENERAL;
  228. else if (strcmp(argv[0],LIST_MESSAGE_DIGEST_COMMANDS) == 0)
  229. list_type = FUNC_TYPE_MD;
  230. else /* strcmp(argv[0],LIST_CIPHER_COMMANDS) == 0 */
  231. list_type = FUNC_TYPE_CIPHER;
  232. bio_stdout = BIO_new_fp(stdout,BIO_NOCLOSE);
  233. for (fp=functions; fp->name != NULL; fp++)
  234. if (fp->type == list_type)
  235. BIO_printf(bio_stdout, "%s\n", fp->name);
  236. BIO_free(bio_stdout);
  237. ret=0;
  238. goto end;
  239. }
  240. else
  241. {
  242. BIO_printf(bio_err,"openssl:Error: '%s' is an invalid command.\n",
  243. argv[0]);
  244. BIO_printf(bio_err, "\nStandard commands");
  245. i=0;
  246. tp=0;
  247. for (fp=functions; fp->name != NULL; fp++)
  248. {
  249. nl=0;
  250. if (((i++) % 5) == 0)
  251. {
  252. BIO_printf(bio_err,"\n");
  253. nl=1;
  254. }
  255. if (fp->type != tp)
  256. {
  257. tp=fp->type;
  258. if (!nl) BIO_printf(bio_err,"\n");
  259. if (tp == FUNC_TYPE_MD)
  260. {
  261. i=1;
  262. BIO_printf(bio_err,
  263. "\nMessage Digest commands (see the `dgst' command for more details)\n");
  264. }
  265. else if (tp == FUNC_TYPE_CIPHER)
  266. {
  267. i=1;
  268. BIO_printf(bio_err,"\nCipher commands (see the `enc' command for more details)\n");
  269. }
  270. }
  271. BIO_printf(bio_err,"%-15s",fp->name);
  272. }
  273. BIO_printf(bio_err,"\n\n");
  274. ret=0;
  275. }
  276. end:
  277. return(ret);
  278. }
  279. static int SortFnByName(const void *_f1,const void *_f2)
  280. {
  281. const FUNCTION *f1=_f1;
  282. const FUNCTION *f2=_f2;
  283. if(f1->type != f2->type)
  284. return f1->type-f2->type;
  285. return strcmp(f1->name,f2->name);
  286. }
  287. static LHASH *prog_init(void)
  288. {
  289. LHASH *ret;
  290. FUNCTION *f;
  291. int i;
  292. /* Purely so it looks nice when the user hits ? */
  293. for(i=0,f=functions ; f->name != NULL ; ++f,++i)
  294. ;
  295. qsort(functions,i,sizeof *functions,SortFnByName);
  296. if ((ret=lh_new(hash,cmp)) == NULL) return(NULL);
  297. for (f=functions; f->name != NULL; f++)
  298. lh_insert(ret,f);
  299. return(ret);
  300. }
  301. static int MS_CALLBACK cmp(FUNCTION *a, FUNCTION *b)
  302. {
  303. return(strncmp(a->name,b->name,8));
  304. }
  305. static unsigned long MS_CALLBACK hash(FUNCTION *a)
  306. {
  307. return(lh_strhash(a->name));
  308. }