CC = clang |
CFLAGS = |
DEPS = |
OBJ = modexp2pubkey.o |
LIBS = -lssl -lcrypto |
%.o: %.c $(DEPS) |
$(CC) -c -o $@$<$(CFLAGS) |
modexp2pubkey: $(OBJ) |
$(CC) -o $@$^$(CFLAGS)$(LIBS) |
.PHONY: clean |
clean: |
rm -f *.o |
#include<string.h> |
#include<openssl/rsa.h> |
#include<openssl/evp.h> |
#include<openssl/bn.h> |
#include<openssl/pem.h> |
// cheating, .. ignoring deprecation warnings |
#pragma GCC diagnostic ignored '-Wdeprecated-declarations' |
unsignedchar *base64_decode(constchar* base64data, int* len) { |
BIO *b64, *bmem; |
size_t length = strlen(base64data); |
unsignedchar *buffer = (unsignedchar *)malloc(length); |
b64 = BIO_new(BIO_f_base64()); |
BIO_set_flags(b64, BIO_FLAGS_BASE64_NO_NL); |
bmem = BIO_new_mem_buf((void*)base64data, length); |
bmem = BIO_push(b64, bmem); |
*len = BIO_read(bmem, buffer, length); |
BIO_free_all(bmem); |
return buffer; |
} |
BIGNUM* bignum_base64_decode(constchar* base64bignum) { |
BIGNUM* bn = NULL; |
int len; |
unsignedchar* data = base64_decode(base64bignum, &len); |
if (len) { |
bn = BN_bin2bn(data, len, NULL); |
} |
free(data); |
return bn; |
} |
EVP_PKEY* RSA_fromBase64(constchar* modulus_b64, constchar* exp_b64) { |
BIGNUM *n = bignum_base64_decode(modulus_b64); |
BIGNUM *e = bignum_base64_decode(exp_b64); |
if (!n) printf('Invalid encoding for modulusn'); |
if (!e) printf('Invalid encoding for public exponentn'); |
if (e && n) { |
EVP_PKEY* pRsaKey = EVP_PKEY_new(); |
RSA* rsa = RSA_new(); |
rsa->e = e; |
rsa->n = n; |
EVP_PKEY_assign_RSA(pRsaKey, rsa); |
return pRsaKey; |
} else { |
if (n) BN_free(n); |
if (e) BN_free(e); |
returnNULL; |
} |
} |
voidassert_syntax(int argc, char** argv) { |
if (argc != 4) { |
fprintf(stderr, 'Description: %s takes a RSA public key modulus and exponent in base64 encoding and produces a public key file in PEM format.n', argv[0]); |
fprintf(stderr, 'syntax: %s <modulus_base64> <exp_base64> <output_file>n', argv[0]); |
exit(1); |
} |
} |
intmain(int argc, char** argv) { |
assert_syntax(argc, argv); |
constchar* modulus = argv[1]; |
constchar* exp = argv[2]; |
constchar* filename = argv[3]; |
EVP_PKEY* pkey = RSA_fromBase64(modulus, exp); |
if (pkey NULL) { |
fprintf(stderr, 'an error occurred :(n'); |
return2; |
} else { |
printf('success decoded into RSA public keyn'); |
FILE* file = fopen(filename, 'w'); |
PEM_write_PUBKEY(file, pkey); |
fflush(file); |
fclose(file); |
printf('written to file: %sn', filename); |
} |
return0; |
} |