1/* ==================================================================== 2 * Copyright (c) 2007 The OpenSSL Project. All rights reserved. 3 * 4 * Redistribution and use in source and binary forms, with or without 5 * modification, are permitted provided that the following conditions 6 * are met: 7 * 8 * 1. Redistributions of source code must retain the above copyright 9 * notice, this list of conditions and the following disclaimer. 10 * 11 * 2. Redistributions in binary form must reproduce the above copyright 12 * notice, this list of conditions and the following disclaimer in 13 * the documentation and/or other materials provided with the 14 * distribution. 15 * 16 * 3. All advertising materials mentioning features or use of this 17 * software must display the following acknowledgment: 18 * "This product includes software developed by the OpenSSL Project 19 * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" 20 * 21 * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to 22 * endorse or promote products derived from this software without 23 * prior written permission. For written permission, please contact 24 * openssl-core@openssl.org. 25 * 26 * 5. Products derived from this software may not be called "OpenSSL" 27 * nor may "OpenSSL" appear in their names without prior written 28 * permission of the OpenSSL Project. 29 * 30 * 6. Redistributions of any form whatsoever must retain the following 31 * acknowledgment: 32 * "This product includes software developed by the OpenSSL Project 33 * for use in the OpenSSL Toolkit (http://www.openssl.org/)" 34 * 35 * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY 36 * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 37 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 38 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR 39 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 40 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 41 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 42 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 43 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 44 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 45 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED 46 * OF THE POSSIBILITY OF SUCH DAMAGE. 47 * 48 */ 49 50void do_print_errors(void); 51int hex2bin(const char *in, unsigned char *out); 52unsigned char *hex2bin_m(const char *in, long *plen); 53int do_hex2bn(BIGNUM **pr, const char *in); 54int do_bn_print(FILE *out, BIGNUM *bn); 55int do_bn_print_name(FILE *out, const char *name, BIGNUM *bn); 56int parse_line(char **pkw, char **pval, char *linebuf, char *olinebuf); 57BIGNUM *hex2bn(const char *in); 58int bin2hex(const unsigned char *in,int len,char *out); 59void pv(const char *tag,const unsigned char *val,int len); 60int tidy_line(char *linebuf, char *olinebuf); 61int bint2bin(const char *in, int len, unsigned char *out); 62int bin2bint(const unsigned char *in,int len,char *out); 63void PrintValue(char *tag, unsigned char *val, int len); 64void OutputValue(char *tag, unsigned char *val, int len, FILE *rfp,int bitmode); 65 66void do_print_errors(void) 67 { 68 const char *file, *data; 69 int line, flags; 70 unsigned long l; 71 while ((l = ERR_get_error_line_data(&file, &line, &data, &flags))) 72 { 73 fprintf(stderr, "ERROR:%lx:lib=%d,func=%d,reason=%d" 74 ":file=%s:line=%d:%s\n", 75 l, ERR_GET_LIB(l), ERR_GET_FUNC(l), ERR_GET_REASON(l), 76 file, line, flags & ERR_TXT_STRING ? data : ""); 77 } 78 } 79 80int hex2bin(const char *in, unsigned char *out) 81 { 82 int n1, n2; 83 unsigned char ch; 84 85 for (n1=0,n2=0 ; in[n1] && in[n1] != '\n' ; ) 86 { /* first byte */ 87 if ((in[n1] >= '0') && (in[n1] <= '9')) 88 ch = in[n1++] - '0'; 89 else if ((in[n1] >= 'A') && (in[n1] <= 'F')) 90 ch = in[n1++] - 'A' + 10; 91 else if ((in[n1] >= 'a') && (in[n1] <= 'f')) 92 ch = in[n1++] - 'a' + 10; 93 else 94 return -1; 95 if(!in[n1]) 96 { 97 out[n2++]=ch; 98 break; 99 } 100 out[n2] = ch << 4; 101 /* second byte */ 102 if ((in[n1] >= '0') && (in[n1] <= '9')) 103 ch = in[n1++] - '0'; 104 else if ((in[n1] >= 'A') && (in[n1] <= 'F')) 105 ch = in[n1++] - 'A' + 10; 106 else if ((in[n1] >= 'a') && (in[n1] <= 'f')) 107 ch = in[n1++] - 'a' + 10; 108 else 109 return -1; 110 out[n2++] |= ch; 111 } 112 return n2; 113 } 114 115unsigned char *hex2bin_m(const char *in, long *plen) 116 { 117 unsigned char *p; 118 p = OPENSSL_malloc((strlen(in) + 1)/2); 119 *plen = hex2bin(in, p); 120 return p; 121 } 122 123int do_hex2bn(BIGNUM **pr, const char *in) 124 { 125 unsigned char *p; 126 long plen; 127 int r = 0; 128 p = hex2bin_m(in, &plen); 129 if (!p) 130 return 0; 131 if (!*pr) 132 *pr = BN_new(); 133 if (!*pr) 134 return 0; 135 if (BN_bin2bn(p, plen, *pr)) 136 r = 1; 137 OPENSSL_free(p); 138 return r; 139 } 140 141int do_bn_print(FILE *out, BIGNUM *bn) 142 { 143 int len, i; 144 unsigned char *tmp; 145 len = BN_num_bytes(bn); 146 if (len == 0) 147 { 148 fputs("00", out); 149 return 1; 150 } 151 152 tmp = OPENSSL_malloc(len); 153 if (!tmp) 154 { 155 fprintf(stderr, "Memory allocation error\n"); 156 return 0; 157 } 158 BN_bn2bin(bn, tmp); 159 for (i = 0; i < len; i++) 160 fprintf(out, "%02x", tmp[i]); 161 OPENSSL_free(tmp); 162 return 1; 163 } 164 165int do_bn_print_name(FILE *out, const char *name, BIGNUM *bn) 166 { 167 int r; 168 fprintf(out, "%s = ", name); 169 r = do_bn_print(out, bn); 170 if (!r) 171 return 0; 172 fputs("\n", out); 173 return 1; 174 } 175 176int parse_line(char **pkw, char **pval, char *linebuf, char *olinebuf) 177 { 178 char *keyword, *value, *p, *q; 179 strcpy(linebuf, olinebuf); 180 keyword = linebuf; 181 /* Skip leading space */ 182 while (isspace((unsigned char)*keyword)) 183 keyword++; 184 185 /* Look for = sign */ 186 p = strchr(linebuf, '='); 187 188 /* If no '=' exit */ 189 if (!p) 190 return 0; 191 192 q = p - 1; 193 194 /* Remove trailing space */ 195 while (isspace((unsigned char)*q)) 196 *q-- = 0; 197 198 *p = 0; 199 value = p + 1; 200 201 /* Remove leading space from value */ 202 while (isspace((unsigned char)*value)) 203 value++; 204 205 /* Remove trailing space from value */ 206 p = value + strlen(value) - 1; 207 208 while (*p == '\n' || isspace((unsigned char)*p)) 209 *p-- = 0; 210 211 *pkw = keyword; 212 *pval = value; 213 return 1; 214 } 215 216BIGNUM *hex2bn(const char *in) 217 { 218 BIGNUM *p=NULL; 219 220 if (!do_hex2bn(&p, in)) 221 return NULL; 222 223 return p; 224 } 225 226int bin2hex(const unsigned char *in,int len,char *out) 227 { 228 int n1, n2; 229 unsigned char ch; 230 231 for (n1=0,n2=0 ; n1 < len ; ++n1) 232 { 233 ch=in[n1] >> 4; 234 if (ch <= 0x09) 235 out[n2++]=ch+'0'; 236 else 237 out[n2++]=ch-10+'a'; 238 ch=in[n1] & 0x0f; 239 if(ch <= 0x09) 240 out[n2++]=ch+'0'; 241 else 242 out[n2++]=ch-10+'a'; 243 } 244 out[n2]='\0'; 245 return n2; 246 } 247 248void pv(const char *tag,const unsigned char *val,int len) 249 { 250 char obuf[2048]; 251 252 bin2hex(val,len,obuf); 253 printf("%s = %s\n",tag,obuf); 254 } 255 256/* To avoid extensive changes to test program at this stage just convert 257 * the input line into an acceptable form. Keyword lines converted to form 258 * "keyword = value\n" no matter what white space present, all other lines 259 * just have leading and trailing space removed. 260 */ 261 262int tidy_line(char *linebuf, char *olinebuf) 263 { 264 char *keyword, *value, *p, *q; 265 strcpy(linebuf, olinebuf); 266 keyword = linebuf; 267 /* Skip leading space */ 268 while (isspace((unsigned char)*keyword)) 269 keyword++; 270 /* Look for = sign */ 271 p = strchr(linebuf, '='); 272 273 /* If no '=' just chop leading, trailing ws */ 274 if (!p) 275 { 276 p = keyword + strlen(keyword) - 1; 277 while (*p == '\n' || isspace((unsigned char)*p)) 278 *p-- = 0; 279 strcpy(olinebuf, keyword); 280 strcat(olinebuf, "\n"); 281 return 1; 282 } 283 284 q = p - 1; 285 286 /* Remove trailing space */ 287 while (isspace((unsigned char)*q)) 288 *q-- = 0; 289 290 *p = 0; 291 value = p + 1; 292 293 /* Remove leading space from value */ 294 while (isspace((unsigned char)*value)) 295 value++; 296 297 /* Remove trailing space from value */ 298 p = value + strlen(value) - 1; 299 300 while (*p == '\n' || isspace((unsigned char)*p)) 301 *p-- = 0; 302 303 strcpy(olinebuf, keyword); 304 strcat(olinebuf, " = "); 305 strcat(olinebuf, value); 306 strcat(olinebuf, "\n"); 307 308 return 1; 309 } 310 311/* NB: this return the number of _bits_ read */ 312int bint2bin(const char *in, int len, unsigned char *out) 313 { 314 int n; 315 316 memset(out,0,len); 317 for(n=0 ; n < len ; ++n) 318 if(in[n] == '1') 319 out[n/8]|=(0x80 >> (n%8)); 320 return len; 321 } 322 323int bin2bint(const unsigned char *in,int len,char *out) 324 { 325 int n; 326 327 for(n=0 ; n < len ; ++n) 328 out[n]=(in[n/8]&(0x80 >> (n%8))) ? '1' : '0'; 329 return n; 330 } 331 332/*-----------------------------------------------*/ 333 334void PrintValue(char *tag, unsigned char *val, int len) 335{ 336#if VERBOSE 337 char obuf[2048]; 338 int olen; 339 olen = bin2hex(val, len, obuf); 340 printf("%s = %.*s\n", tag, olen, obuf); 341#endif 342} 343 344void OutputValue(char *tag, unsigned char *val, int len, FILE *rfp,int bitmode) 345 { 346 char obuf[2048]; 347 int olen; 348 349 if(bitmode) 350 olen=bin2bint(val,len,obuf); 351 else 352 olen=bin2hex(val,len,obuf); 353 354 fprintf(rfp, "%s = %.*s\n", tag, olen, obuf); 355#if VERBOSE 356 printf("%s = %.*s\n", tag, olen, obuf); 357#endif 358 } 359 360