summaryrefslogtreecommitdiff
path: root/src/usr.bin/openssl/rand.c
diff options
context:
space:
mode:
authorjsing <>2014-08-27 14:59:44 +0000
committerjsing <>2014-08-27 14:59:44 +0000
commit1fbc8b7e3211e362b5507749d1c5b692dcb8c64f (patch)
treed84799ea674d39450c109ebc4c3cb39140e5201e /src/usr.bin/openssl/rand.c
parent10e31157bd2d409218ed09f4b52af2de773a8a0f (diff)
downloadopenbsd-1fbc8b7e3211e362b5507749d1c5b692dcb8c64f.tar.gz
openbsd-1fbc8b7e3211e362b5507749d1c5b692dcb8c64f.tar.bz2
openbsd-1fbc8b7e3211e362b5507749d1c5b692dcb8c64f.zip
Implement table-driven option parsing that allows an application to
specify what its valid options are and where it wants them to be stored. This also allows for usage to be generated, almost for free, ensuring that the options and usage are automatically kept in sync. This will allow for a single option parsing implementation, rather than the current one-hand-rolled-option-parsing-and-random-usage-implementation per application. As a starting point, port the openssl(1) rand application to the new option parsing and usage (along with associated code clean up). With input from doug@. ok bcook@ doug@
Diffstat (limited to '')
-rw-r--r--src/usr.bin/openssl/rand.c149
1 files changed, 75 insertions, 74 deletions
diff --git a/src/usr.bin/openssl/rand.c b/src/usr.bin/openssl/rand.c
index 0800157a35..61c7013340 100644
--- a/src/usr.bin/openssl/rand.c
+++ b/src/usr.bin/openssl/rand.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: rand.c,v 1.1 2014/08/26 17:47:25 jsing Exp $ */ 1/* $OpenBSD: rand.c,v 1.2 2014/08/27 14:59:44 jsing Exp $ */
2/* ==================================================================== 2/* ====================================================================
3 * Copyright (c) 1998-2001 The OpenSSL Project. All rights reserved. 3 * Copyright (c) 1998-2001 The OpenSSL Project. All rights reserved.
4 * 4 *
@@ -63,123 +63,124 @@
63#include <openssl/err.h> 63#include <openssl/err.h>
64#include <openssl/rand.h> 64#include <openssl/rand.h>
65 65
66/* -out file - write to file 66struct {
67 * -base64 - base64 encode output 67 int base64;
68 * -hex - hex encode output 68 char *engine;
69 * num - write 'num' bytes 69 int hex;
70 */ 70 char *outfile;
71} rand_config;
72
73struct option rand_options[] = {
74 {
75 .name = "base64",
76 .desc = "Perform base64 encoding on output",
77 .type = OPTION_FLAG,
78 .opt.flag = &rand_config.base64,
79 },
80#ifndef OPENSSL_NO_ENGINE
81 {
82 .name = "engine",
83 .argname = "id",
84 .desc = "Use the engine specified by the given identifier",
85 .type = OPTION_ARG,
86 .opt.arg = &rand_config.engine,
87 },
88#endif
89 {
90 .name = "hex",
91 .desc = "Hexadecimal output",
92 .type = OPTION_FLAG,
93 .opt.flag = &rand_config.hex,
94 },
95 {
96 .name = "out",
97 .argname = "file",
98 .desc = "Write to the given file instead of standard output",
99 .type = OPTION_ARG,
100 .opt.arg = &rand_config.outfile,
101 },
102 {},
103};
104
105static void
106rand_usage()
107{
108 fprintf(stderr,
109 "usage: rand [-base64 | -hex] [-engine id] [-out file] num\n");
110 options_usage(rand_options);
111}
71 112
72int rand_main(int, char **); 113int rand_main(int, char **);
73 114
74int 115int
75rand_main(int argc, char **argv) 116rand_main(int argc, char **argv)
76{ 117{
77 int i, r, ret = 1; 118 char *num_bytes = NULL;
78 int badopt; 119 int ret = 1;
79 char *outfile = NULL; 120 int badopt = 0;
80 int base64 = 0;
81 int hex = 0;
82 BIO *out = NULL;
83 int num = -1; 121 int num = -1;
84#ifndef OPENSSL_NO_ENGINE 122 int i, r;
85 char *engine = NULL; 123 BIO *out = NULL;
86#endif
87 124
88 badopt = 0; 125 if (options_parse(argc, argv, rand_options, &num_bytes) != 0) {
89 i = 0; 126 rand_usage();
90 while (!badopt && argv[++i] != NULL) { 127 return (1);
91 if (strcmp(argv[i], "-out") == 0) {
92 if ((argv[i + 1] != NULL) && (outfile == NULL))
93 outfile = argv[++i];
94 else
95 badopt = 1;
96 }
97#ifndef OPENSSL_NO_ENGINE
98 else if (strcmp(argv[i], "-engine") == 0) {
99 if ((argv[i + 1] != NULL) && (engine == NULL))
100 engine = argv[++i];
101 else
102 badopt = 1;
103 }
104#endif
105 else if (strcmp(argv[i], "-base64") == 0) {
106 if (!base64)
107 base64 = 1;
108 else
109 badopt = 1;
110 } else if (strcmp(argv[i], "-hex") == 0) {
111 if (!hex)
112 hex = 1;
113 else
114 badopt = 1;
115 } else if (isdigit((unsigned char) argv[i][0])) {
116 if (num < 0) {
117 r = sscanf(argv[i], "%d", &num);
118 if (r == 0 || num < 0)
119 badopt = 1;
120 } else
121 badopt = 1;
122 } else
123 badopt = 1;
124 } 128 }
125 129
126 if (hex && base64) 130 if (num_bytes != NULL) {
131 r = sscanf(num_bytes, "%d", &num);
132 if (r == 0 || num < 0)
133 badopt = 1;
134 } else
127 badopt = 1; 135 badopt = 1;
128 136
129 if (num < 0) 137 if (rand_config.hex && rand_config.base64)
130 badopt = 1; 138 badopt = 1;
131 139
132 if (badopt) { 140 if (badopt) {
133 BIO_printf(bio_err, "Usage: rand [options] num\n"); 141 rand_usage();
134 BIO_printf(bio_err, "where options are\n");
135 BIO_printf(bio_err, "-out file - write to file\n");
136#ifndef OPENSSL_NO_ENGINE
137 BIO_printf(bio_err, "-engine e - use engine e, possibly a hardware device.\n");
138#endif
139 BIO_printf(bio_err, "-base64 - base64 encode output\n");
140 BIO_printf(bio_err, "-hex - hex encode output\n");
141 goto err; 142 goto err;
142 } 143 }
144
143#ifndef OPENSSL_NO_ENGINE 145#ifndef OPENSSL_NO_ENGINE
144 setup_engine(bio_err, engine, 0); 146 setup_engine(bio_err, rand_config.engine, 0);
145#endif 147#endif
146 148
147 out = BIO_new(BIO_s_file()); 149 out = BIO_new(BIO_s_file());
148 if (out == NULL) 150 if (out == NULL)
149 goto err; 151 goto err;
150 if (outfile != NULL) 152 if (rand_config.outfile != NULL)
151 r = BIO_write_filename(out, outfile); 153 r = BIO_write_filename(out, rand_config.outfile);
152 else { 154 else
153 r = BIO_set_fp(out, stdout, BIO_NOCLOSE | BIO_FP_TEXT); 155 r = BIO_set_fp(out, stdout, BIO_NOCLOSE | BIO_FP_TEXT);
154 }
155 if (r <= 0) 156 if (r <= 0)
156 goto err; 157 goto err;
157 158 if (rand_config.base64) {
158 if (base64) {
159 BIO *b64 = BIO_new(BIO_f_base64()); 159 BIO *b64 = BIO_new(BIO_f_base64());
160 if (b64 == NULL) 160 if (b64 == NULL)
161 goto err; 161 goto err;
162 out = BIO_push(b64, out); 162 out = BIO_push(b64, out);
163 } 163 }
164
164 while (num > 0) { 165 while (num > 0) {
165 unsigned char buf[4096]; 166 unsigned char buf[4096];
166 int chunk; 167 int chunk;
167 168
168 chunk = num; 169 chunk = num;
169 if (chunk > (int) sizeof(buf)) 170 if (chunk > (int) sizeof(buf))
170 chunk = sizeof buf; 171 chunk = sizeof(buf);
171 r = RAND_bytes(buf, chunk); 172 r = RAND_bytes(buf, chunk);
172 if (r <= 0) 173 if (r <= 0)
173 goto err; 174 goto err;
174 if (!hex) 175 if (rand_config.hex) {
175 BIO_write(out, buf, chunk);
176 else {
177 for (i = 0; i < chunk; i++) 176 for (i = 0; i < chunk; i++)
178 BIO_printf(out, "%02x", buf[i]); 177 BIO_printf(out, "%02x", buf[i]);
179 } 178 } else
179 BIO_write(out, buf, chunk);
180 num -= chunk; 180 num -= chunk;
181 } 181 }
182 if (hex) 182
183 if (rand_config.hex)
183 BIO_puts(out, "\n"); 184 BIO_puts(out, "\n");
184 (void) BIO_flush(out); 185 (void) BIO_flush(out);
185 186