replace EVP_MD_CTX_verify() stuff with RSA_verify()/ECDSA_verify()

since the EVP_MD_CTX stuff doesn't seem to exist on osx at all.
This commit is contained in:
Klas Lindfors
2015-03-20 14:02:24 +01:00
parent 8ada864df9
commit 9db6d3d45a
3 changed files with 75 additions and 46 deletions
+22 -1
View File
@@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2014 Yubico AB * Copyright (c) 2014-2015 Yubico AB
* All rights reserved. * All rights reserved.
* *
* This program is free software: you can redistribute it and/or modify * This program is free software: you can redistribute it and/or modify
@@ -216,3 +216,24 @@ bool set_component_with_len(unsigned char **in_ptr, const BIGNUM *bn, int elemen
*in_ptr += BN_bn2bin(bn, *in_ptr); *in_ptr += BN_bn2bin(bn, *in_ptr);
return true; return true;
} }
bool prepare_rsa_signature(const unsigned char *in, unsigned int in_len, unsigned char *out, unsigned int *out_len, int nid) {
X509_SIG digestInfo;
X509_ALGOR algor;
ASN1_TYPE parameter;
ASN1_OCTET_STRING digest;
unsigned char data[1024];
memcpy(data, in, in_len);
digestInfo.algor = &algor;
digestInfo.algor->algorithm = OBJ_nid2obj(nid);
digestInfo.algor->parameter = &parameter;
digestInfo.algor->parameter->type = V_ASN1_NULL;
digestInfo.algor->parameter->value.ptr = NULL;
digestInfo.digest = &digest;
digestInfo.digest->data = data;
digestInfo.digest->length = (int)in_len;
*out_len = (unsigned int)i2d_X509_SIG(&digestInfo, &out);
return true;
}
+2
View File
@@ -45,5 +45,7 @@ unsigned char get_algorithm(EVP_PKEY*);
FILE *open_file(const char*, int); FILE *open_file(const char*, int);
int get_object_id(enum enum_slot slot); int get_object_id(enum enum_slot slot);
bool set_component_with_len(unsigned char**, const BIGNUM*, int); bool set_component_with_len(unsigned char**, const BIGNUM*, int);
bool prepare_rsa_signature(const unsigned char*, unsigned int, unsigned char*,
unsigned int*, int);
#endif #endif
+51 -45
View File
@@ -45,6 +45,7 @@
#include <openssl/pem.h> #include <openssl/pem.h>
#include <openssl/pkcs12.h> #include <openssl/pkcs12.h>
#include <openssl/rand.h> #include <openssl/rand.h>
#include <openssl/err.h>
#include "cmdline.h" #include "cmdline.h"
#include "util.h" #include "util.h"
@@ -1087,7 +1088,7 @@ static bool sign_file(ykpiv_state *state, const char *input, const char *output,
unsigned char hashed[EVP_MAX_MD_SIZE]; unsigned char hashed[EVP_MAX_MD_SIZE];
bool ret = false; bool ret = false;
int algo; int algo;
int nid; const EVP_MD *md;
sscanf(slot, "%2x", &key); sscanf(slot, "%2x", &key);
@@ -1121,21 +1122,17 @@ static bool sign_file(ykpiv_state *state, const char *input, const char *output,
} }
{ {
const EVP_MD *md;
EVP_MD_CTX *mdctx; EVP_MD_CTX *mdctx;
switch(hash) { switch(hash) {
case hash_arg_SHA1: case hash_arg_SHA1:
md = EVP_sha1(); md = EVP_sha1();
nid = NID_sha1;
break; break;
case hash_arg_SHA256: case hash_arg_SHA256:
md = EVP_sha256(); md = EVP_sha256();
nid = NID_sha256;
break; break;
case hash_arg_SHA512: case hash_arg_SHA512:
md = EVP_sha512(); md = EVP_sha512();
nid = NID_sha512;
break; break;
case hash__NULL: case hash__NULL:
default: default:
@@ -1159,24 +1156,7 @@ static bool sign_file(ykpiv_state *state, const char *input, const char *output,
} }
if(algo == YKPIV_ALGO_RSA1024 || algo == YKPIV_ALGO_RSA2048) { if(algo == YKPIV_ALGO_RSA1024 || algo == YKPIV_ALGO_RSA2048) {
X509_SIG digestInfo; prepare_rsa_signature(hashed, hash_len, hashed, &hash_len, EVP_MD_type(md));
X509_ALGOR algor;
ASN1_TYPE parameter;
ASN1_OCTET_STRING digest;
unsigned char buf[1024];
unsigned char *ptr = hashed;
memcpy(buf, hashed, hash_len);
digestInfo.algor = &algor;
digestInfo.algor->algorithm = OBJ_nid2obj(nid);
digestInfo.algor->parameter = &parameter;
digestInfo.algor->parameter->type = V_ASN1_NULL;
digestInfo.algor->parameter->value.ptr = NULL;
digestInfo.digest = &digest;
digestInfo.digest->data = buf;
digestInfo.digest->length = (int)hash_len;
hash_len = (unsigned int)i2d_X509_SIG(&digestInfo, &ptr);
} }
{ {
@@ -1364,11 +1344,10 @@ static bool test_signature(ykpiv_state *state, enum enum_slot slot,
enum enum_key_format cert_format, int verbose) { enum enum_key_format cert_format, int verbose) {
const EVP_MD *md; const EVP_MD *md;
bool ret = false; bool ret = false;
unsigned char data[EVP_MAX_MD_SIZE]; unsigned char data[1024];
unsigned int data_len; unsigned int data_len;
X509 *x509 = NULL; X509 *x509 = NULL;
EVP_PKEY *pubkey; EVP_PKEY *pubkey;
EVP_PKEY_CTX *verify_ctx = NULL;
FILE *input_file = open_file(input_file_name, INPUT); FILE *input_file = open_file(input_file_name, INPUT);
if(!input_file) { if(!input_file) {
@@ -1428,6 +1407,9 @@ static bool test_signature(ykpiv_state *state, enum enum_slot slot,
{ {
unsigned char signature[1024]; unsigned char signature[1024];
unsigned char encoded[1024];
unsigned char *ptr = data;
unsigned int enc_len;
size_t sig_len = sizeof(signature); size_t sig_len = sizeof(signature);
int key = 0; int key = 0;
unsigned char algorithm; unsigned char algorithm;
@@ -1439,31 +1421,58 @@ static bool test_signature(ykpiv_state *state, enum enum_slot slot,
} }
algorithm = get_algorithm(pubkey); algorithm = get_algorithm(pubkey);
if(algorithm == 0) { if(algorithm == 0) {
return false; goto test_out;
} }
sscanf(cmdline_parser_slot_values[slot], "%2x", &key); sscanf(cmdline_parser_slot_values[slot], "%2x", &key);
if(ykpiv_sign_data(state, data, data_len, signature, &sig_len, algorithm, key) if(algorithm == YKPIV_ALGO_RSA1024 || algorithm == YKPIV_ALGO_RSA2048) {
prepare_rsa_signature(data, data_len, encoded, &enc_len, EVP_MD_type(md));
ptr = encoded;
} else {
enc_len = data_len;
}
if(ykpiv_sign_data(state, ptr, enc_len, signature, &sig_len, algorithm, key)
!= YKPIV_OK) { != YKPIV_OK) {
fprintf(stderr, "Failed signing test data.\n"); fprintf(stderr, "Failed signing test data.\n");
goto test_out; goto test_out;
} }
{ switch(algorithm) {
verify_ctx = EVP_PKEY_CTX_new(pubkey, NULL); case YKPIV_ALGO_RSA1024:
if(!verify_ctx) { case YKPIV_ALGO_RSA2048:
fprintf(stderr, "Allocation failure.\n"); {
RSA *rsa = EVP_PKEY_get1_RSA(pubkey);
if(!rsa) {
fprintf(stderr, "Failed getting RSA pubkey.\n");
goto test_out;
}
if(RSA_verify(EVP_MD_type(md), data, data_len, signature, sig_len, rsa) == 1) {
fprintf(stderr, "Successful RSA verification.\n");
ret = true;
goto test_out;
} else {
fprintf(stderr, "Failed RSA verification.\n");
goto test_out;
}
}
break;
case YKPIV_ALGO_ECCP256:
{
EC_KEY *ec = EVP_PKEY_get1_EC_KEY(pubkey);
if(ECDSA_verify(0, data, (int)data_len, signature, (int)sig_len, ec) == 1) {
fprintf(stderr, "Successful ECDSA verification.\n");
ret = true;
goto test_out;
} else {
fprintf(stderr, "Failed ECDSA verification.\n");
goto test_out;
}
}
break;
default:
fprintf(stderr, "Unknown algorithm.\n");
goto test_out; goto test_out;
}
if(EVP_PKEY_verify_init(verify_ctx) == 0) {
fprintf(stderr, "Failed initializing verify context.\n");
goto test_out;
}
if(EVP_PKEY_verify(verify_ctx, signature, sig_len, data, data_len) == 1) {
fprintf(stderr, "Successfully verified signature.\n");
ret = true;
} else {
fprintf(stderr, "Signature verification failed.\n");
}
} }
} }
test_out: test_out:
@@ -1473,9 +1482,6 @@ test_out:
if(input_file != stdin) { if(input_file != stdin) {
fclose(input_file); fclose(input_file);
} }
if(verify_ctx) {
EVP_PKEY_CTX_free(verify_ctx);
}
return ret; return ret;
} }