1 /* $OpenBSD: keynote-keygen.c,v 1.17 2001/09/13 17:55:10 angelos Exp $ */ 2 /* 3 * The author of this code is Angelos D. Keromytis (angelos@dsl.cis.upenn.edu) 4 * 5 * This code was written by Angelos D. Keromytis in Philadelphia, PA, USA, 6 * in April-May 1998 7 * 8 * Copyright (C) 1998, 1999 by Angelos D. Keromytis. 9 * 10 * Permission to use, copy, and modify this software with or without fee 11 * is hereby granted, provided that this entire notice is included in 12 * all copies of any software which is or includes a copy or 13 * modification of this software. 14 * 15 * THIS SOFTWARE IS BEING PROVIDED "AS IS", WITHOUT ANY EXPRESS OR 16 * IMPLIED WARRANTY. IN PARTICULAR, THE AUTHORS MAKES NO 17 * REPRESENTATION OR WARRANTY OF ANY KIND CONCERNING THE 18 * MERCHANTABILITY OF THIS SOFTWARE OR ITS FITNESS FOR ANY PARTICULAR 19 * PURPOSE. 20 */ 21 22 #if HAVE_CONFIG_H 23 #include "config.h" 24 #endif /* HAVE_CONFIG_H */ 25 26 #include <sys/types.h> 27 #include <sys/stat.h> 28 #include <stdlib.h> 29 #include <stdio.h> 30 #include <ctype.h> 31 32 #if STDC_HEADERS 33 #include <string.h> 34 #endif /* STDC_HEADERS */ 35 36 #if HAVE_FCNTL_H 37 #include <fcntl.h> 38 #endif /* HAVE_FCNTL_H */ 39 40 #if HAVE_IO_H 41 #include <io.h> 42 #elif HAVE_UNISTD_H 43 #include <unistd.h> 44 #endif /* HAVE_IO_H */ 45 46 #include "header.h" 47 #include "keynote.h" 48 #include "assertion.h" 49 #include "signature.h" 50 51 void 52 keygenusage(void) 53 { 54 fprintf(stderr, "Arguments:\n"); 55 fprintf(stderr, "\t<AlgorithmName> <keysize> " 56 "<PublicKeyFile> <PrivateKeyFile> [<print-offset>] " 57 "[<print-length>]\n"); 58 } 59 60 /* 61 * Print the specified number of spaces. 62 */ 63 void 64 print_space(FILE *fp, int n) 65 { 66 while (n--) 67 fprintf(fp, " "); 68 } 69 70 /* 71 * Output a key, properly formatted. 72 */ 73 void 74 print_key(FILE *fp, char *algname, char *key, int start, int length) 75 { 76 int i, k; 77 78 print_space(fp, start); 79 fprintf(fp, "\"%s", algname); 80 81 for (i = 0, k = strlen(algname) + 2; i < strlen(key); i++, k++) 82 { 83 if (k == length) 84 { 85 if (i == strlen(key)) 86 { 87 fprintf(fp, "\"\n"); 88 return; 89 } 90 91 fprintf(fp, "\\\n"); 92 print_space(fp, start); 93 i--; 94 k = 0; 95 } 96 else 97 fprintf(fp, "%c", key[i]); 98 } 99 100 fprintf(fp, "\"\n"); 101 } 102 103 void 104 keynote_keygen(int argc, char *argv[]) 105 { 106 int begin = KEY_PRINT_OFFSET, prlen = KEY_PRINT_LENGTH; 107 #if defined(CRYPTO) || defined(PGPLIB) 108 char *foo, *privalgname, seed[SEED_LEN]; 109 int alg, enc, ienc, len = 0, counter; 110 struct keynote_deckey dc; 111 unsigned long h; 112 DSA *dsa; 113 RSA *rsa; 114 FILE *fp; 115 #endif /* CRYPTO || PGPLIB */ 116 char *algname; 117 118 if ((argc != 5) && (argc != 6) && (argc != 7)) 119 { 120 keygenusage(); 121 exit(0); 122 } 123 124 /* Fix algorithm name */ 125 if (argv[1][strlen(argv[1]) - 1] != ':') 126 { 127 fprintf(stderr, "Algorithm name [%s] should be terminated with a " 128 "colon, fixing.\n", argv[1]); 129 algname = (char *) calloc(strlen(argv[1]) + 2, sizeof(char)); 130 if (algname == (char *) NULL) 131 { 132 perror("calloc()"); 133 exit(1); 134 } 135 136 strcpy(algname, argv[1]); 137 algname[strlen(algname)] = ':'; 138 } 139 else 140 algname = argv[1]; 141 142 if (argc > 5) 143 { 144 begin = atoi(argv[5]); 145 if (begin <= -1) 146 { 147 fprintf(stderr, "Erroneous value for print-offset parameter.\n"); 148 exit(1); 149 } 150 } 151 152 if (argc > 6) 153 { 154 prlen = atoi(argv[6]); 155 if (prlen <= 0) 156 { 157 fprintf(stderr, "Erroneous value for print-length parameter.\n"); 158 exit(1); 159 } 160 } 161 162 if (strlen(algname) + 2 > prlen) 163 { 164 fprintf(stderr, "Parameter ``print-length'' should be larger " 165 "than the length of AlgorithmName (%lu)\n", 166 (unsigned long) strlen(algname)); 167 exit(1); 168 } 169 170 #if defined(CRYPTO) || defined(PGPLIB) 171 alg = keynote_get_key_algorithm(algname, &enc, &ienc); 172 len = atoi(argv[2]); 173 174 if (len <= 0) 175 { 176 fprintf(stderr, "Invalid specified keysize %d\n", len); 177 exit(1); 178 } 179 180 if ((alg == KEYNOTE_ALGORITHM_DSA) && 181 (ienc == INTERNAL_ENC_ASN1) && 182 ((enc == ENCODING_HEX) || (enc == ENCODING_BASE64))) 183 { 184 RAND_bytes(seed, SEED_LEN); 185 186 dsa = DSA_generate_parameters(len, seed, SEED_LEN, &counter, &h, NULL 187 #if SSLEAY_VERSION_NUMBER >= 0x0900 188 , NULL 189 #endif /* SSLEAY_VERSION_NUMBER */ 190 ); 191 192 if (dsa == (DSA *) NULL) 193 { 194 ERR_print_errors_fp(stderr); 195 exit(1); 196 } 197 198 if (DSA_generate_key(dsa) != 1) 199 { 200 ERR_print_errors_fp(stderr); 201 exit(1); 202 } 203 204 dc.dec_algorithm = KEYNOTE_ALGORITHM_DSA; 205 dc.dec_key = (void *) dsa; 206 207 foo = kn_encode_key(&dc, ienc, enc, KEYNOTE_PUBLIC_KEY); 208 if (foo == (char *) NULL) 209 { 210 fprintf(stderr, "Error encoding key (errno %d)\n", keynote_errno); 211 exit(1); 212 } 213 214 if (!strcmp(argv[3], "-")) 215 fp = stdout; 216 else 217 { 218 fp = fopen(argv[3], "w"); 219 if (fp == (FILE *) NULL) 220 { 221 perror(argv[3]); 222 exit(1); 223 } 224 } 225 226 print_key(fp, algname, foo, begin, prlen); 227 free(foo); 228 229 if (strcmp(argv[3], "-")) 230 fclose(fp); 231 232 foo = kn_encode_key(&dc, ienc, enc, KEYNOTE_PRIVATE_KEY); 233 if (foo == (char *) NULL) 234 { 235 fprintf(stderr, "Error encoding key (errno %d)\n", keynote_errno); 236 exit(1); 237 } 238 239 if (!strcmp(argv[4], "-")) 240 { 241 fp = stdout; 242 if (!strcmp(argv[3], "-")) 243 printf("===========================\n"); 244 } 245 else 246 { 247 fp = fopen(argv[4], "w"); 248 if (fp == (FILE *) NULL) 249 { 250 perror(argv[4]); 251 exit(1); 252 } 253 } 254 255 privalgname = (char *) calloc(strlen(KEYNOTE_PRIVATE_KEY_PREFIX) + 256 strlen(foo) + 1, sizeof(char)); 257 if (privalgname == (char *) NULL) 258 { 259 perror("calloc()"); 260 exit(1); 261 } 262 sprintf(privalgname, "%s%s", KEYNOTE_PRIVATE_KEY_PREFIX, algname); 263 print_key(fp, privalgname, foo, begin, prlen); 264 free(privalgname); 265 free(foo); 266 267 if (strcmp(argv[4], "-")) 268 fclose(fp); 269 270 exit(0); 271 } 272 273 if ((alg == KEYNOTE_ALGORITHM_RSA) && 274 (ienc == INTERNAL_ENC_PKCS1) && 275 ((enc == ENCODING_HEX) || (enc == ENCODING_BASE64))) 276 { 277 rsa = RSA_generate_key(len, DEFAULT_PUBLIC, NULL 278 #if SSLEAY_VERSION_NUMBER >= 0x0900 279 , NULL 280 #endif /* SSLEAY_VERSION_NUMBER */ 281 ); 282 283 if (rsa == (RSA *) NULL) 284 { 285 ERR_print_errors_fp(stderr); 286 exit(1); 287 } 288 289 dc.dec_algorithm = KEYNOTE_ALGORITHM_RSA; 290 dc.dec_key = (void *) rsa; 291 292 foo = kn_encode_key(&dc, ienc, enc, KEYNOTE_PUBLIC_KEY); 293 if (foo == (char *) NULL) 294 { 295 fprintf(stderr, "Error encoding key (errno %d)\n", keynote_errno); 296 exit(1); 297 } 298 299 if (!strcmp(argv[3], "-")) 300 fp = stdout; 301 else 302 { 303 fp = fopen(argv[3], "w"); 304 if (fp == (FILE *) NULL) 305 { 306 perror(argv[3]); 307 exit(1); 308 } 309 } 310 311 print_key(fp, algname, foo, begin, prlen); 312 free(foo); 313 314 if (strcmp(argv[3], "-")) 315 fclose(fp); 316 317 foo = kn_encode_key(&dc, ienc, enc, KEYNOTE_PRIVATE_KEY); 318 if (foo == (char *) NULL) 319 { 320 fprintf(stderr, "Error encoding key (errno %d)\n", keynote_errno); 321 exit(1); 322 } 323 324 if (!strcmp(argv[4], "-")) 325 { 326 fp = stdout; 327 if (!strcmp(argv[3], "-")) 328 printf("===========================\n"); 329 } 330 else 331 { 332 fp = fopen(argv[4], "w"); 333 if (fp == (FILE *) NULL) 334 { 335 perror(argv[4]); 336 exit(1); 337 } 338 } 339 340 privalgname = (char *) calloc(strlen(KEYNOTE_PRIVATE_KEY_PREFIX) + 341 strlen(foo) + 1, sizeof(char)); 342 if (privalgname == (char *) NULL) 343 { 344 perror("calloc()"); 345 exit(1); 346 } 347 sprintf(privalgname, "%s%s", KEYNOTE_PRIVATE_KEY_PREFIX, algname); 348 print_key(fp, privalgname, foo, begin, prlen); 349 free(privalgname); 350 free(foo); 351 352 if (strcmp(argv[4], "-")) 353 fclose(fp); 354 355 exit(0); 356 } 357 358 /* More algorithms here */ 359 #endif /* CRYPTO */ 360 361 fprintf(stderr, "Unknown/unsupported algorithm [%s]\n", algname); 362 exit(1); 363 } 364