plainrsa-gen.c revision f8a6a7636d53a5730c58ae041e4e09ae12e1657c
1f8a6a7636d53a5730c58ae041e4e09ae12e1657cChia-chi Yeh/* $NetBSD: plainrsa-gen.c,v 1.6 2011/02/11 10:07:19 tteras Exp $ */ 20a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang 30a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang/* Id: plainrsa-gen.c,v 1.6 2005/04/21 09:08:40 monas Exp */ 40a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang/* 50a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * Copyright (C) 2004 SuSE Linux AG, Nuernberg, Germany. 60a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * Contributed by: Michal Ludvig <mludvig@suse.cz>, SUSE Labs 70a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * All rights reserved. 80a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * 90a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * Redistribution and use in source and binary forms, with or without 100a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * modification, are permitted provided that the following conditions 110a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * are met: 120a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * 1. Redistributions of source code must retain the above copyright 130a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * notice, this list of conditions and the following disclaimer. 140a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * 2. Redistributions in binary form must reproduce the above copyright 150a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * notice, this list of conditions and the following disclaimer in the 160a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * documentation and/or other materials provided with the distribution. 170a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * 3. Neither the name of the project nor the names of its contributors 180a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * may be used to endorse or promote products derived from this software 190a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * without specific prior written permission. 200a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * 210a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND 220a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 230a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 240a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE 250a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 260a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 270a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 280a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 290a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 300a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 310a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * SUCH DAMAGE. 320a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang */ 330a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang 340a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang/* This file contains a generator for FreeS/WAN-style ipsec.secrets RSA keys. */ 350a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang 360a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#include "config.h" 370a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang 380a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#include <stdio.h> 390a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#include <string.h> 400a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#include <errno.h> 410a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang 420a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#include <sys/types.h> 430a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#include <sys/stat.h> 440a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#include <sys/socket.h> 450a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#include <unistd.h> 46f8a6a7636d53a5730c58ae041e4e09ae12e1657cChia-chi Yeh#include <fcntl.h> 470a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang 480a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#include <openssl/bio.h> 490a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#include <openssl/bn.h> 500a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#include <openssl/err.h> 510a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#include <openssl/objects.h> 52f8a6a7636d53a5730c58ae041e4e09ae12e1657cChia-chi Yeh#include <openssl/pem.h> 530a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#include <openssl/rsa.h> 540a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#include <openssl/evp.h> 550a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#ifdef HAVE_OPENSSL_ENGINE_H 560a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#include <openssl/engine.h> 570a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#endif 580a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang 590a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#include "misc.h" 600a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#include "vmbuf.h" 610a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#include "plog.h" 620a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#include "crypto_openssl.h" 630a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang 640a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#include "package_version.h" 650a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang 660a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangvoid 670a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangusage (char *argv0) 680a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang{ 690a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang fprintf(stderr, "Plain RSA key generator, part of %s\n", TOP_PACKAGE_STRING); 700a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang fprintf(stderr, "By Michal Ludvig (http://www.logix.cz/michal)\n"); 710a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang fprintf(stderr, "\n"); 720a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang fprintf(stderr, "Usage: %s [options]\n", argv0); 730a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang fprintf(stderr, "\n"); 740a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang fprintf(stderr, " -b bits Generate <bits> long RSA key (default=1024)\n"); 750a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang fprintf(stderr, " -e pubexp Public exponent to use (default=0x3)\n"); 760a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang fprintf(stderr, " -f filename Filename to store the key to (default=stdout)\n"); 77f8a6a7636d53a5730c58ae041e4e09ae12e1657cChia-chi Yeh fprintf(stderr, " -i filename Input source for format conversion\n"); 780a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang fprintf(stderr, " -h Help\n"); 790a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang fprintf(stderr, "\n"); 800a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang fprintf(stderr, "Report bugs to <ipsec-tools-devel@lists.sourceforge.net>\n"); 810a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang exit(1); 820a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang} 830a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang 840a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang/* 850a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * See RFC 2065, section 3.5 for details about the output format. 860a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang */ 870a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangvchar_t * 88f8a6a7636d53a5730c58ae041e4e09ae12e1657cChia-chi Yehmix_b64_pubkey(const RSA *key) 890a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang{ 900a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang char *binbuf; 910a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang long binlen, ret; 920a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang vchar_t *res; 930a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang 940a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang binlen = 1 + BN_num_bytes(key->e) + BN_num_bytes(key->n); 950a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang binbuf = malloc(binlen); 960a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang memset(binbuf, 0, binlen); 970a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang binbuf[0] = BN_bn2bin(key->e, (unsigned char *) &binbuf[1]); 980a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang ret = BN_bn2bin(key->n, (unsigned char *) (&binbuf[binbuf[0] + 1])); 990a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang if (1 + binbuf[0] + ret != binlen) { 1000a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang plog(LLV_ERROR, LOCATION, NULL, 1010a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang "Pubkey generation failed. This is really strange...\n"); 1020a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang return NULL; 1030a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang } 1040a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang 1050a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang return base64_encode(binbuf, binlen); 1060a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang} 1070a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang 1080a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangchar * 1090a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wanglowercase(char *input) 1100a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang{ 1110a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang char *ptr = input; 1120a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang while (*ptr) { 1130a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang if (*ptr >= 'A' && *ptr <= 'F') 1140a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang *ptr -= 'A' - 'a'; 1150a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang *ptr++; 1160a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang } 1170a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang 1180a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang return input; 1190a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang} 1200a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang 1210a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangint 122f8a6a7636d53a5730c58ae041e4e09ae12e1657cChia-chi Yehprint_rsa_key(FILE *fp, const RSA *key) 1230a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang{ 1240a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang vchar_t *pubkey64 = NULL; 1250a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang 1260a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang pubkey64 = mix_b64_pubkey(key); 1270a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang if (!pubkey64) { 1280a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang fprintf(stderr, "mix_b64_pubkey(): %s\n", eay_strerror()); 1290a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang return -1; 1300a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang } 1310a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang 1320a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang fprintf(fp, "# : PUB 0s%s\n", pubkey64->v); 1330a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang fprintf(fp, ": RSA\t{\n"); 134f8a6a7636d53a5730c58ae041e4e09ae12e1657cChia-chi Yeh fprintf(fp, "\t# RSA %d bits\n", BN_num_bits(key->n)); 1350a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang fprintf(fp, "\t# pubkey=0s%s\n", pubkey64->v); 1360a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang fprintf(fp, "\tModulus: 0x%s\n", lowercase(BN_bn2hex(key->n))); 1370a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang fprintf(fp, "\tPublicExponent: 0x%s\n", lowercase(BN_bn2hex(key->e))); 1380a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang fprintf(fp, "\tPrivateExponent: 0x%s\n", lowercase(BN_bn2hex(key->d))); 1390a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang fprintf(fp, "\tPrime1: 0x%s\n", lowercase(BN_bn2hex(key->p))); 1400a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang fprintf(fp, "\tPrime2: 0x%s\n", lowercase(BN_bn2hex(key->q))); 1410a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang fprintf(fp, "\tExponent1: 0x%s\n", lowercase(BN_bn2hex(key->dmp1))); 1420a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang fprintf(fp, "\tExponent2: 0x%s\n", lowercase(BN_bn2hex(key->dmq1))); 1430a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang fprintf(fp, "\tCoefficient: 0x%s\n", lowercase(BN_bn2hex(key->iqmp))); 1440a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang fprintf(fp, " }\n"); 1450a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang 1460a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang vfree(pubkey64); 147f8a6a7636d53a5730c58ae041e4e09ae12e1657cChia-chi Yeh return 0; 148f8a6a7636d53a5730c58ae041e4e09ae12e1657cChia-chi Yeh} 149f8a6a7636d53a5730c58ae041e4e09ae12e1657cChia-chi Yeh 150f8a6a7636d53a5730c58ae041e4e09ae12e1657cChia-chi Yehint 151f8a6a7636d53a5730c58ae041e4e09ae12e1657cChia-chi Yehprint_public_rsa_key(FILE *fp, const RSA *key) 152f8a6a7636d53a5730c58ae041e4e09ae12e1657cChia-chi Yeh{ 153f8a6a7636d53a5730c58ae041e4e09ae12e1657cChia-chi Yeh vchar_t *pubkey64 = NULL; 1540a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang 155f8a6a7636d53a5730c58ae041e4e09ae12e1657cChia-chi Yeh pubkey64 = mix_b64_pubkey(key); 156f8a6a7636d53a5730c58ae041e4e09ae12e1657cChia-chi Yeh if (!pubkey64) { 157f8a6a7636d53a5730c58ae041e4e09ae12e1657cChia-chi Yeh fprintf(stderr, "mix_b64_pubkey(): %s\n", eay_strerror()); 158f8a6a7636d53a5730c58ae041e4e09ae12e1657cChia-chi Yeh return -1; 159f8a6a7636d53a5730c58ae041e4e09ae12e1657cChia-chi Yeh } 160f8a6a7636d53a5730c58ae041e4e09ae12e1657cChia-chi Yeh 161f8a6a7636d53a5730c58ae041e4e09ae12e1657cChia-chi Yeh fprintf(fp, ": PUB 0s%s\n", pubkey64->v); 162f8a6a7636d53a5730c58ae041e4e09ae12e1657cChia-chi Yeh 163f8a6a7636d53a5730c58ae041e4e09ae12e1657cChia-chi Yeh vfree(pubkey64); 1640a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang return 0; 1650a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang} 1660a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang 1670a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangint 168f8a6a7636d53a5730c58ae041e4e09ae12e1657cChia-chi Yehconvert_rsa_key(FILE *fpout, FILE *fpin) 169f8a6a7636d53a5730c58ae041e4e09ae12e1657cChia-chi Yeh{ 170f8a6a7636d53a5730c58ae041e4e09ae12e1657cChia-chi Yeh int ret; 171f8a6a7636d53a5730c58ae041e4e09ae12e1657cChia-chi Yeh RSA *key = NULL; 172f8a6a7636d53a5730c58ae041e4e09ae12e1657cChia-chi Yeh 173f8a6a7636d53a5730c58ae041e4e09ae12e1657cChia-chi Yeh key = PEM_read_RSAPrivateKey(fpin, NULL, NULL, NULL); 174f8a6a7636d53a5730c58ae041e4e09ae12e1657cChia-chi Yeh if (key) { 175f8a6a7636d53a5730c58ae041e4e09ae12e1657cChia-chi Yeh ret = print_rsa_key(fpout, key); 176f8a6a7636d53a5730c58ae041e4e09ae12e1657cChia-chi Yeh RSA_free(key); 177f8a6a7636d53a5730c58ae041e4e09ae12e1657cChia-chi Yeh 178f8a6a7636d53a5730c58ae041e4e09ae12e1657cChia-chi Yeh return ret; 179f8a6a7636d53a5730c58ae041e4e09ae12e1657cChia-chi Yeh } 180f8a6a7636d53a5730c58ae041e4e09ae12e1657cChia-chi Yeh 181f8a6a7636d53a5730c58ae041e4e09ae12e1657cChia-chi Yeh rewind(fpin); 182f8a6a7636d53a5730c58ae041e4e09ae12e1657cChia-chi Yeh 183f8a6a7636d53a5730c58ae041e4e09ae12e1657cChia-chi Yeh key = PEM_read_RSA_PUBKEY(fpin, NULL, NULL, NULL); 184f8a6a7636d53a5730c58ae041e4e09ae12e1657cChia-chi Yeh if (key) { 185f8a6a7636d53a5730c58ae041e4e09ae12e1657cChia-chi Yeh ret = print_public_rsa_key(fpout, key); 186f8a6a7636d53a5730c58ae041e4e09ae12e1657cChia-chi Yeh RSA_free(key); 187f8a6a7636d53a5730c58ae041e4e09ae12e1657cChia-chi Yeh 188f8a6a7636d53a5730c58ae041e4e09ae12e1657cChia-chi Yeh return ret; 189f8a6a7636d53a5730c58ae041e4e09ae12e1657cChia-chi Yeh } 190f8a6a7636d53a5730c58ae041e4e09ae12e1657cChia-chi Yeh 191f8a6a7636d53a5730c58ae041e4e09ae12e1657cChia-chi Yeh /* Implement parsing of input stream containing 192f8a6a7636d53a5730c58ae041e4e09ae12e1657cChia-chi Yeh * private or public "plainrsa" formatted text. 193f8a6a7636d53a5730c58ae041e4e09ae12e1657cChia-chi Yeh * Convert the result to PEM formatted output. 194f8a6a7636d53a5730c58ae041e4e09ae12e1657cChia-chi Yeh * 195f8a6a7636d53a5730c58ae041e4e09ae12e1657cChia-chi Yeh * This seemingly needs manual use of prsaparse(). 196f8a6a7636d53a5730c58ae041e4e09ae12e1657cChia-chi Yeh * An expert ought to do this. */ 197f8a6a7636d53a5730c58ae041e4e09ae12e1657cChia-chi Yeh 198f8a6a7636d53a5730c58ae041e4e09ae12e1657cChia-chi Yeh fprintf(stderr, "convert_rsa_key: %s\n", "Only conversion from PEM at this time"); 199f8a6a7636d53a5730c58ae041e4e09ae12e1657cChia-chi Yeh return -1; 200f8a6a7636d53a5730c58ae041e4e09ae12e1657cChia-chi Yeh} 201f8a6a7636d53a5730c58ae041e4e09ae12e1657cChia-chi Yeh 202f8a6a7636d53a5730c58ae041e4e09ae12e1657cChia-chi Yehint 203f8a6a7636d53a5730c58ae041e4e09ae12e1657cChia-chi Yehgen_rsa_key(FILE *fp, size_t bits, unsigned long exp) 204f8a6a7636d53a5730c58ae041e4e09ae12e1657cChia-chi Yeh{ 205f8a6a7636d53a5730c58ae041e4e09ae12e1657cChia-chi Yeh int ret; 206f8a6a7636d53a5730c58ae041e4e09ae12e1657cChia-chi Yeh RSA *key; 207f8a6a7636d53a5730c58ae041e4e09ae12e1657cChia-chi Yeh 208f8a6a7636d53a5730c58ae041e4e09ae12e1657cChia-chi Yeh key = RSA_generate_key(bits, exp, NULL, NULL); 209f8a6a7636d53a5730c58ae041e4e09ae12e1657cChia-chi Yeh if (!key) { 210f8a6a7636d53a5730c58ae041e4e09ae12e1657cChia-chi Yeh fprintf(stderr, "RSA_generate_key(): %s\n", eay_strerror()); 211f8a6a7636d53a5730c58ae041e4e09ae12e1657cChia-chi Yeh return -1; 212f8a6a7636d53a5730c58ae041e4e09ae12e1657cChia-chi Yeh } 213f8a6a7636d53a5730c58ae041e4e09ae12e1657cChia-chi Yeh 214f8a6a7636d53a5730c58ae041e4e09ae12e1657cChia-chi Yeh ret = print_rsa_key(fp, key); 215f8a6a7636d53a5730c58ae041e4e09ae12e1657cChia-chi Yeh RSA_free(key); 216f8a6a7636d53a5730c58ae041e4e09ae12e1657cChia-chi Yeh 217f8a6a7636d53a5730c58ae041e4e09ae12e1657cChia-chi Yeh return ret; 218f8a6a7636d53a5730c58ae041e4e09ae12e1657cChia-chi Yeh} 219f8a6a7636d53a5730c58ae041e4e09ae12e1657cChia-chi Yeh 220f8a6a7636d53a5730c58ae041e4e09ae12e1657cChia-chi Yehint 2210a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangmain (int argc, char *argv[]) 2220a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang{ 223f8a6a7636d53a5730c58ae041e4e09ae12e1657cChia-chi Yeh FILE *fp = stdout, *fpin = NULL; 2240a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang size_t bits = 1024; 2250a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang unsigned int pubexp = 0x3; 2260a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang struct stat st; 2270a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang extern char *optarg; 2280a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang extern int optind; 229f8a6a7636d53a5730c58ae041e4e09ae12e1657cChia-chi Yeh int c, fd = -1, fdin = -1; 230f8a6a7636d53a5730c58ae041e4e09ae12e1657cChia-chi Yeh char *fname = NULL, *finput = NULL; 2310a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang 232f8a6a7636d53a5730c58ae041e4e09ae12e1657cChia-chi Yeh while ((c = getopt(argc, argv, "e:b:f:i:h")) != -1) 2330a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang switch (c) { 2340a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang case 'e': 2350a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang if (strncmp(optarg, "0x", 2) == 0) 2360a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang sscanf(optarg, "0x%x", &pubexp); 2370a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang else 2380a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang pubexp = atoi(optarg); 2390a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang break; 2400a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang case 'b': 2410a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang bits = atoi(optarg); 2420a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang break; 2430a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang case 'f': 2440a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang fname = optarg; 2450a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang break; 246f8a6a7636d53a5730c58ae041e4e09ae12e1657cChia-chi Yeh case 'i': 247f8a6a7636d53a5730c58ae041e4e09ae12e1657cChia-chi Yeh finput = optarg; 248f8a6a7636d53a5730c58ae041e4e09ae12e1657cChia-chi Yeh break; 2490a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang case 'h': 2500a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang default: 2510a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang usage(argv[0]); 2520a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang } 2530a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang 2540a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang if (fname) { 255f8a6a7636d53a5730c58ae041e4e09ae12e1657cChia-chi Yeh umask(0077); 256f8a6a7636d53a5730c58ae041e4e09ae12e1657cChia-chi Yeh /* Restrictive access due to private key material. */ 257f8a6a7636d53a5730c58ae041e4e09ae12e1657cChia-chi Yeh fd = open(fname, O_WRONLY | O_CREAT | O_EXCL | O_NOFOLLOW, S_IRUSR | S_IWUSR); 258f8a6a7636d53a5730c58ae041e4e09ae12e1657cChia-chi Yeh if (fd < 0) { 259f8a6a7636d53a5730c58ae041e4e09ae12e1657cChia-chi Yeh if (errno == EEXIST) 260f8a6a7636d53a5730c58ae041e4e09ae12e1657cChia-chi Yeh fprintf(stderr, "%s: file exists! Please use a different name.\n", fname); 261f8a6a7636d53a5730c58ae041e4e09ae12e1657cChia-chi Yeh else 262f8a6a7636d53a5730c58ae041e4e09ae12e1657cChia-chi Yeh fprintf(stderr, "%s: %s\n", fname, strerror(errno)); 2630a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang exit(1); 2640a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang } 265f8a6a7636d53a5730c58ae041e4e09ae12e1657cChia-chi Yeh fp = fdopen(fd, "w"); 2660a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang if (fp == NULL) { 2670a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang fprintf(stderr, "%s: %s\n", fname, strerror(errno)); 268f8a6a7636d53a5730c58ae041e4e09ae12e1657cChia-chi Yeh close(fd); 2690a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang exit(1); 2700a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang } 2710a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang } 2720a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang 273f8a6a7636d53a5730c58ae041e4e09ae12e1657cChia-chi Yeh if (finput) { 274f8a6a7636d53a5730c58ae041e4e09ae12e1657cChia-chi Yeh /* Restrictive access once more. Do not be fooled by a link. */ 275f8a6a7636d53a5730c58ae041e4e09ae12e1657cChia-chi Yeh fdin = open(finput, O_RDONLY | O_NOFOLLOW); 276f8a6a7636d53a5730c58ae041e4e09ae12e1657cChia-chi Yeh if (fdin < 0) { 277f8a6a7636d53a5730c58ae041e4e09ae12e1657cChia-chi Yeh if (errno == ELOOP) 278f8a6a7636d53a5730c58ae041e4e09ae12e1657cChia-chi Yeh fprintf(stderr, "%s: file is a link. Discarded for security.\n", fname); 279f8a6a7636d53a5730c58ae041e4e09ae12e1657cChia-chi Yeh if (fp) 280f8a6a7636d53a5730c58ae041e4e09ae12e1657cChia-chi Yeh fclose(fp); 281f8a6a7636d53a5730c58ae041e4e09ae12e1657cChia-chi Yeh exit(1); 282f8a6a7636d53a5730c58ae041e4e09ae12e1657cChia-chi Yeh } 283f8a6a7636d53a5730c58ae041e4e09ae12e1657cChia-chi Yeh fpin = fdopen(fdin, "r"); 284f8a6a7636d53a5730c58ae041e4e09ae12e1657cChia-chi Yeh if (fpin == NULL) { 285f8a6a7636d53a5730c58ae041e4e09ae12e1657cChia-chi Yeh fprintf(stderr, "%s: %s\n", fname, strerror(errno)); 286f8a6a7636d53a5730c58ae041e4e09ae12e1657cChia-chi Yeh close(fdin); 287f8a6a7636d53a5730c58ae041e4e09ae12e1657cChia-chi Yeh if (fp) 288f8a6a7636d53a5730c58ae041e4e09ae12e1657cChia-chi Yeh fclose(fp); 289f8a6a7636d53a5730c58ae041e4e09ae12e1657cChia-chi Yeh exit(1); 290f8a6a7636d53a5730c58ae041e4e09ae12e1657cChia-chi Yeh } 291f8a6a7636d53a5730c58ae041e4e09ae12e1657cChia-chi Yeh 292f8a6a7636d53a5730c58ae041e4e09ae12e1657cChia-chi Yeh } 293f8a6a7636d53a5730c58ae041e4e09ae12e1657cChia-chi Yeh 2940a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang ploginit(); 2950a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang eay_init(); 2960a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang 297f8a6a7636d53a5730c58ae041e4e09ae12e1657cChia-chi Yeh if (fpin) 298f8a6a7636d53a5730c58ae041e4e09ae12e1657cChia-chi Yeh convert_rsa_key(fp, fpin); 299f8a6a7636d53a5730c58ae041e4e09ae12e1657cChia-chi Yeh else 300f8a6a7636d53a5730c58ae041e4e09ae12e1657cChia-chi Yeh gen_rsa_key(fp, bits, pubexp); 3010a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang 3020a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang fclose(fp); 303f8a6a7636d53a5730c58ae041e4e09ae12e1657cChia-chi Yeh if (fpin) 304f8a6a7636d53a5730c58ae041e4e09ae12e1657cChia-chi Yeh fclose(fpin); 3050a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang 3060a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang return 0; 3070a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang} 308