rand.c 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177
  1. /* apps/rand.c */
  2. #include "apps.h"
  3. #include <ctype.h>
  4. #include <stdio.h>
  5. #include <string.h>
  6. #include <openssl/bio.h>
  7. #include <openssl/err.h>
  8. #include <openssl/rand.h>
  9. #include <openssl/engine.h>
  10. #undef PROG
  11. #define PROG rand_main
  12. /* -out file - write to file
  13. * -rand file:file - PRNG seed files
  14. * -base64 - encode output
  15. * num - write 'num' bytes
  16. */
  17. int MAIN(int, char **);
  18. int MAIN(int argc, char **argv)
  19. {
  20. ENGINE *e = NULL;
  21. int i, r, ret = 1;
  22. int badopt;
  23. char *outfile = NULL;
  24. char *inrand = NULL;
  25. int base64 = 0;
  26. BIO *out = NULL;
  27. int num = -1;
  28. char *engine=NULL;
  29. apps_startup();
  30. if (bio_err == NULL)
  31. if ((bio_err = BIO_new(BIO_s_file())) != NULL)
  32. BIO_set_fp(bio_err, stderr, BIO_NOCLOSE|BIO_FP_TEXT);
  33. badopt = 0;
  34. i = 0;
  35. while (!badopt && argv[++i] != NULL)
  36. {
  37. if (strcmp(argv[i], "-out") == 0)
  38. {
  39. if ((argv[i+1] != NULL) && (outfile == NULL))
  40. outfile = argv[++i];
  41. else
  42. badopt = 1;
  43. }
  44. else if (strcmp(argv[i], "-engine") == 0)
  45. {
  46. if ((argv[i+1] != NULL) && (engine == NULL))
  47. engine = argv[++i];
  48. else
  49. badopt = 1;
  50. }
  51. else if (strcmp(argv[i], "-rand") == 0)
  52. {
  53. if ((argv[i+1] != NULL) && (inrand == NULL))
  54. inrand = argv[++i];
  55. else
  56. badopt = 1;
  57. }
  58. else if (strcmp(argv[i], "-base64") == 0)
  59. {
  60. if (!base64)
  61. base64 = 1;
  62. else
  63. badopt = 1;
  64. }
  65. else if (isdigit((unsigned char)argv[i][0]))
  66. {
  67. if (num < 0)
  68. {
  69. r = sscanf(argv[i], "%d", &num);
  70. if (r == 0 || num < 0)
  71. badopt = 1;
  72. }
  73. else
  74. badopt = 1;
  75. }
  76. else
  77. badopt = 1;
  78. }
  79. if (num < 0)
  80. badopt = 1;
  81. if (badopt)
  82. {
  83. BIO_printf(bio_err, "Usage: rand [options] num\n");
  84. BIO_printf(bio_err, "where options are\n");
  85. BIO_printf(bio_err, "-out file - write to file\n");
  86. BIO_printf(bio_err, "-engine e - use engine e, possibly a hardware device.\n");
  87. BIO_printf(bio_err, "-rand file%cfile%c... - seed PRNG from files\n", LIST_SEPARATOR_CHAR, LIST_SEPARATOR_CHAR);
  88. BIO_printf(bio_err, "-base64 - encode output\n");
  89. goto err;
  90. }
  91. if (engine != NULL)
  92. {
  93. if((e = ENGINE_by_id(engine)) == NULL)
  94. {
  95. BIO_printf(bio_err,"invalid engine \"%s\"\n",
  96. engine);
  97. goto err;
  98. }
  99. if(!ENGINE_set_default(e, ENGINE_METHOD_ALL))
  100. {
  101. BIO_printf(bio_err,"can't use that engine\n");
  102. goto err;
  103. }
  104. BIO_printf(bio_err,"engine \"%s\" set.\n", engine);
  105. /* Free our "structural" reference. */
  106. ENGINE_free(e);
  107. }
  108. app_RAND_load_file(NULL, bio_err, (inrand != NULL));
  109. if (inrand != NULL)
  110. BIO_printf(bio_err,"%ld semi-random bytes loaded\n",
  111. app_RAND_load_files(inrand));
  112. out = BIO_new(BIO_s_file());
  113. if (out == NULL)
  114. goto err;
  115. if (outfile != NULL)
  116. r = BIO_write_filename(out, outfile);
  117. else
  118. {
  119. r = BIO_set_fp(out, stdout, BIO_NOCLOSE | BIO_FP_TEXT);
  120. #ifdef OPENSSL_SYS_VMS
  121. {
  122. BIO *tmpbio = BIO_new(BIO_f_linebuffer());
  123. out = BIO_push(tmpbio, out);
  124. }
  125. #endif
  126. }
  127. if (r <= 0)
  128. goto err;
  129. if (base64)
  130. {
  131. BIO *b64 = BIO_new(BIO_f_base64());
  132. if (b64 == NULL)
  133. goto err;
  134. out = BIO_push(b64, out);
  135. }
  136. while (num > 0)
  137. {
  138. unsigned char buf[4096];
  139. int chunk;
  140. chunk = num;
  141. if (chunk > sizeof buf)
  142. chunk = sizeof buf;
  143. r = RAND_bytes(buf, chunk);
  144. if (r <= 0)
  145. goto err;
  146. BIO_write(out, buf, chunk);
  147. num -= chunk;
  148. }
  149. BIO_flush(out);
  150. app_RAND_write_file(NULL, bio_err);
  151. ret = 0;
  152. err:
  153. ERR_print_errors(bio_err);
  154. if (out)
  155. BIO_free_all(out);
  156. EXIT(ret);
  157. }