Commit 638414d0 authored by Jan Včelák's avatar Jan Včelák 🚀
Browse files

add demo programs

parent 37019a65
demo_gnutls
demo_openssl
CFLAGS=-std=gnu99 -Wall -g -O2 -Icrypto
openssl_FLAGS=$(shell pkg-config --cflags --libs libcrypto)
gnutls_FLAGS=$(shell pkg-config --cflags --libs "gnutls >= 3.0" nettle hogweed) -lgmp
.PHONY: all clean
all: demo_openssl demo_gnutls
clean:
rm -f demo_openssl demo_gnutls
demo_openssl: demo/main.c demo/openssl.c crypto/openssl_fdh.c
$(CC) $(CFLAGS) $(openssl_FLAGS) -o $@ $^
demo_gnutls: demo/main.c demo/gnutls.c crypto/gnutls_fdh.c crypto/nettle_fdh.c crypto/nettle_mgf.c
$(CC) $(CFLAGS) $(gnutls_FLAGS) -o $@ $^
#pragma once
#include <stdint.h>
#include <stdlib.h>
#define error(fmt, ...) fprintf(stderr, fmt "\n", ##__VA_ARGS__)
void print_hex(const uint8_t *data, size_t len);
const char *demo_name(void);
int demo(const char *filename, const char *hash_name,
const uint8_t *data, size_t data_len);
#include "demo.h"
#include "gnutls_fdh.h"
#include <stdbool.h>
#include <string.h>
#include <stdio.h>
#include <gnutls/abstract.h>
#include <gnutls/x509.h>
const char *demo_name(void)
{
return "GnuTLS";
}
/*!
* Lookup hash function by name.
*/
static const gnutls_digest_algorithm_t lookup_hash(const char *name)
{
for (const gnutls_digest_algorithm_t *h = gnutls_digest_list(); h && *h; h++) {
if (strcasecmp(name, gnutls_digest_get_name(*h)) == 0) {
return *h;
}
}
return 0;
}
/*!
* Convert GnuTLS RSA private key to public key.
*/
static gnutls_pubkey_t pubkey_from_privkey(gnutls_x509_privkey_t x509)
{
gnutls_privkey_t privkey = NULL;
gnutls_privkey_init(&privkey);
if (gnutls_privkey_import_x509(privkey, x509, 0) != 0) {
gnutls_privkey_deinit(privkey);
return NULL;
}
gnutls_pubkey_t pubkey = NULL;
gnutls_pubkey_init(&pubkey);
int r = gnutls_pubkey_import_privkey(pubkey, privkey, 0, 0);
gnutls_privkey_deinit(privkey);
if (r != 0) {
gnutls_pubkey_deinit(pubkey);
return NULL;
}
return pubkey;
}
static bool load_pem(const char *filename, gnutls_datum_t *result_ptr)
{
FILE *file = fopen(filename, "r");
if (!file) {
return false;
}
bool success = false;
gnutls_datum_t result = { 0 };
fseek(file, 0, SEEK_END);
long size = ftell(file);
if (size < 0) {
goto failed;
}
fseek(file, 0, SEEK_SET);
result.size = size;
result.data = malloc(size);
if (!result.data) {
goto failed;
}
if (fread(result.data, result.size, 1, file) != 1) {
free(result.data);
goto failed;
}
*result_ptr = result;
success = true;
failed:
fclose(file);
return success;
}
int demo(const char *filename, const char *hash_name,
const uint8_t *data, size_t data_len)
{
gnutls_digest_algorithm_t hash = lookup_hash(hash_name);
if (hash == 0) {
error("Error retrieving hash function.");
return 1;
}
gnutls_datum_t pem = { 0 };
if (!load_pem(filename, &pem)) {
error("Error reading key file content.");
return 1;
}
gnutls_x509_privkey_t privkey = NULL;
gnutls_x509_privkey_init(&privkey);
int r = gnutls_x509_privkey_import(privkey, &pem, GNUTLS_X509_FMT_PEM);
free(pem.data);
if (r != 0) {
error("Error loading private private key.");
return 1;
}
if (gnutls_x509_privkey_get_pk_algorithm(privkey) != GNUTLS_PK_RSA) {
error("Loaded key is not a RSA key.");
gnutls_x509_privkey_deinit(privkey);
return 1;
}
// sign data
size_t sign_len = gnutls_fdh_len(privkey);
uint8_t sign[sign_len];
size_t written = gnutls_fdh_sign(data, data_len, sign, sign_len, privkey, hash);
if (written != sign_len) {
error("Error creating FDH signature.");
return 1;
}
printf("signature: ");
print_hex(sign, sign_len);
// drop private part of the key and verify the signature
gnutls_pubkey_t pubkey = pubkey_from_privkey(privkey);
if (!pubkey) {
error("Error converting private key to public key.");
return 1;
}
bool valid = gnutls_fdh_verify(data, data_len, sign, sign_len, pubkey, hash);
printf("valid: %s\n", valid ? "true" : "false");
return valid ? 0 : 1;
}
#include <stdbool.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "demo.h"
void print_hex(const uint8_t *data, size_t len)
{
for (size_t i = 0; i < len; i++) {
printf("%02x", data[i]);
}
printf("\n");
}
static void usage(const char *prog_name)
{
printf("usage: %s <hash> <keyfile> <input-string>\n", prog_name);
}
int main(int argc, char *argv[])
{
if (argc != 4) {
usage(argv[0]);
return 1;
}
const char *hash_name = argv[1];
const char *keyfile = argv[2];
const uint8_t *data = (uint8_t *)argv[3];
const size_t data_len = strlen(argv[3]);
printf("# %s\n", demo_name());
printf("input: ");
print_hex(data, data_len);
return demo(keyfile, hash_name, data, data_len);
}
#include "demo.h"
#include "openssl_fdh.h"
#include <stdbool.h>
#include <openssl/evp.h>
#include <openssl/pem.h>
#include <openssl/rsa.h>
const char *demo_name(void)
{
return "OpenSSL";
}
static RSA *key_extract_public(RSA *privkey)
{
RSA *pubkey = RSA_new();
if (!pubkey) {
return NULL;
}
pubkey->n = BN_dup(privkey->n);
pubkey->e = BN_dup(privkey->e);
return pubkey;
}
int demo(const char *filename, const char *hash_name,
const uint8_t *data, size_t data_len)
{
OpenSSL_add_all_digests();
const EVP_MD *hash = EVP_get_digestbyname(hash_name);
if (!hash) {
error("Error retrieving hash function.");
return 1;
}
FILE *pem = fopen(filename, "r");
if (!pem) {
perror("fopen");
return 1;
}
RSA *privkey = PEM_read_RSAPrivateKey(pem, NULL, NULL, NULL);
fclose(pem);
if (!privkey) {
error("Error loading RSA private key.");
return 1;
}
// sign data
size_t sign_len = openssl_fdh_len(privkey);
uint8_t sign[sign_len];
size_t written = openssl_fdh_sign(data, data_len, sign, sign_len, privkey, hash);
if (written != sign_len) {
error("Error creating FDH signature.");
return 1;
}
printf("signature: ");
print_hex(sign, sign_len);
// drop private part of the key and verify the signature
RSA *pubkey = key_extract_public(privkey);
RSA_free(privkey);
if (!pubkey) {
error("Error extracting public RSA parameters from the key.");
return 1;
}
bool valid = openssl_fdh_verify(data, data_len, sign, sign_len, pubkey, hash);
printf("valid: %s\n", valid ? "true" : "false");
RSA_free(pubkey);
return valid ? 0 : 1;
}
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment