wolfssl-examples/pk/rsa-kg/rsa-kg.c

244 lines
6.6 KiB
C

/* rsa-kg.c
*
* Copyright (C) 2006-2020 wolfSSL Inc.
*
* This file is part of wolfSSL.
*
* wolfSSL is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* wolfSSL is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA
*/
/*
* An implementation of RSA key generation using wolfSSL
* Usage:
./rsa-kg -priv <private key filename> -pub <public key filename>
*/
#include <stdio.h>
#include <string.h>
#include <wolfssl/options.h>
#include <wolfssl/wolfcrypt/settings.h>
#include <wolfssl/ssl.h>
#include <wolfssl/wolfcrypt/rsa.h>
#include <wolfssl/wolfcrypt/error-crypt.h>
#define MAX_DER_SIZE 2500
#define MIN_RSA_KEY_SIZE 1024
#define MAX_RSA_KEY_SIZE 4096
#define DEF_RSA_KEY_SIZE 2048
static const char* kRsaPubKey = "./rsa-public.der";
static const char* kRsaPrivKey = "./rsa-private.der";
/* Shows usage information */
void usage()
{
fprintf(stderr, "rsa_kg <options>:\n");
fprintf(stderr, " -bits <num> Size in bits of RSA keys generated\n");
fprintf(stderr, " Range: 1024-4096\n");
fprintf(stderr, " -priv <filename> Private key filename\n");
fprintf(stderr, " -pub <filename> Public key filename\n");
fprintf(stderr, "\n");
}
int main(int argc, char** argv)
{
/* These examples require RSA and Key Gen */
#if !defined(NO_RSA) && defined(WOLFSSL_KEY_GEN)
RsaKey* pRsaKey = NULL;
WC_RNG rng;
int ret = 0;
int bits = DEF_RSA_KEY_SIZE;
int sz;
unsigned char derBuf[MAX_DER_SIZE];
FILE* f;
const char* pubKey = kRsaPubKey;
const char* privKey = kRsaPrivKey;
argc--;
argv++;
while (argc > 0) {
/* Number of bits in RSA key to generate */
if (XSTRNCMP(*argv, "-bits", 6) == 0) {
++argv;
if (--argc == 0) {
fprintf(stderr, "Missing bits value\n");
usage();
return 1;
}
bits = atoi(*argv);
}
else if (XSTRNCMP(*argv, "-priv", 6) == 0) {
++argv;
if (--argc == 0) {
fprintf(stderr, "Missing private key filename\n");
usage();
return 1;
}
privKey = *argv;
}
else if (XSTRNCMP(*argv, "-pub", 6) == 0) {
++argv;
if (--argc == 0) {
fprintf(stderr, "Missing public key filename\n");
usage();
return 1;
}
pubKey = *argv;
}
else if (XSTRNCMP(*argv, "-help", 6) == 0) {
usage();
return 0;
}
else {
fprintf(stderr, "Unrecognized option: %s\n", *argv);
usage();
return 1;
}
argc--;
argv++;
}
/* Check bit count if generating keys */
if ((bits < MIN_RSA_KEY_SIZE || bits > MAX_RSA_KEY_SIZE)) {
fprintf(stderr, "Bits out of range (%d-%d): %d\n", MIN_RSA_KEY_SIZE,
MAX_RSA_KEY_SIZE, bits);
usage();
return 1;
}
#ifdef WOLFSSL_SP_MATH
if (0) {
}
#ifndef WOLFSSL_SP_NO_2048
else if (bits == 2048) {
}
#endif
#ifndef WOLFSSL_SP_NO_3072
else if (bits == 3072) {
}
#endif
#ifdef WOLFSSL_SP_4096
else if (bits == 4096) {
}
#endif
else {
fprintf(stderr, "Bit size not supported with SP_MATH: %d\n", bits);
fprintf(stderr, " wolfSSL compiled to support, in bits:");
#ifndef WOLFSSL_SP_NO_2048
fprintf(stderr, " 2048");
#endif
#ifndef WOLFSSL_SP_NO_3072
fprintf(stderr, " 3072");
#endif
#ifdef WOLFSSL_SP_4096
fprintf(stderr, " 4096");
#endif
fprintf(stderr, "\n");
return 1;
}
#endif
wolfSSL_Debugging_ON();
wolfSSL_Init();
/* Allocate space for RSA key object. */
pRsaKey = malloc(sizeof(RsaKey));
if (!pRsaKey) {
printf("RSA_generate_key failed with error\n");
return MEMORY_E;
}
/* Create a random number generator for key generation. */
ret = wc_InitRng(&rng);
if (ret != 0) {
printf("Init RNG failed %d\n", ret);
free(pRsaKey);
return ret;
}
/* Initialize RSA key object. */
ret = wc_InitRsaKey(pRsaKey, NULL);
if (ret != 0) {
printf("Init RSA key failed %d\n", ret);
wc_FreeRng(&rng);
free(pRsaKey);
return ret;
}
printf("Generating RSA key\n");
/* Generate an RSA key pair. */
if (wc_MakeRsaKey(pRsaKey, bits, WC_RSA_EXPONENT, &rng) != 0) {
printf("failed to create rsa key\n");
}
else {
/* Open public key file. */
f = fopen(pubKey, "wb");
printf("writing public key to %s\n", pubKey);
if (f == NULL) {
printf("unable to write out public key\n");
}
else {
/* Encode public key to DER. */
sz = wc_RsaKeyToPublicDer(pRsaKey, derBuf, sizeof(derBuf));
if (sz <= 0) {
printf("error with rsa to public der %d\n", sz);
}
else {
/* Write DER encoded public key to file. */
fwrite(derBuf, 1, sz, f);
}
fclose(f);
}
/* Open private key file. */
f = fopen(privKey, "wb");
printf("writing public key to %s\n", privKey);
if (f == NULL) {
printf("unable to write out public key\n");
}
else {
/* Encode private key to DER. */
sz = wc_RsaKeyToDer(pRsaKey, derBuf, sizeof(derBuf));
if (sz <= 0) {
printf("error with rsa to public der %d\n", sz);
}
else {
/* Write DER encoded private key to file. */
fwrite(derBuf, 1, sz, f);
}
fclose(f);
}
}
/* Dispose of allocated memory. */
wc_FreeRsaKey(pRsaKey);
wc_FreeRng(&rng);
free(pRsaKey);
wolfSSL_Cleanup();
return 0;
#else
(void)kRsaPubKey;
(void)kRsaPrivKey;
printf("wolfSSL missing build features.\n");
printf("Please build using `./configure --enable-keygen`\n");
return 1;
#endif
}