Skip to content

Commit

Permalink
Add support for X509Certificate through cmd line flag
Browse files Browse the repository at this point in the history
  • Loading branch information
aveenismail committed Sep 18, 2024
1 parent 4357393 commit e77dba6
Show file tree
Hide file tree
Showing 6 changed files with 104 additions and 49 deletions.
15 changes: 13 additions & 2 deletions lib/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,17 @@ set (
yubihsm.c
)

if (ENABLE_CERT_COMPRESS)
set(SOURCE ${SOURCE} ../common/data_compress.c)

find_library(ZLIB zlib PATHS ${ZLIB_LIB_DIR})
include_directories(${ZLIB_INCL_DIR})

find_package(ZLIB REQUIRED)

set(ZLIB_LIBS "ZLIB::ZLIB")
endif()

if(MSVC)
set(SOURCE ${SOURCE} ${CMAKE_CURRENT_SOURCE_DIR}/../common/time_win.c)
endif(MSVC)
Expand Down Expand Up @@ -148,11 +159,11 @@ add_coverage (yubihsm_http)
add_definitions (-DVERSION="${yubihsm_shell_VERSION_MAJOR}.${yubihsm_shell_VERSION_MINOR}.${yubihsm_shell_VERSION_PATCH}")
add_definitions (-DSOVERSION="${yubihsm_shell_VERSION_MAJOR}")

target_link_libraries (yubihsm ${CRYPT_LIBRARY} ${ADDITIONAL_LIBRARY})
target_link_libraries (yubihsm ${CRYPT_LIBRARY} ${ADDITIONAL_LIBRARY} ${ZLIB_LIBS})
target_link_libraries (yubihsm_usb ${USB_LIBRARY})
target_link_libraries (yubihsm_http ${HTTP_LIBRARY})
if(ENABLE_STATIC)
target_link_libraries (yubihsm_static ${CRYPT_LIBRARY} ${ADDITIONAL_LIBRARY} ${HTTP_LIBRARY} ${USB_LIBRARY})
target_link_libraries (yubihsm_static ${CRYPT_LIBRARY} ${ADDITIONAL_LIBRARY} ${HTTP_LIBRARY} ${USB_LIBRARY} ${ZLIB_LIBS})
endif(ENABLE_STATIC)

configure_file(${CMAKE_CURRENT_SOURCE_DIR}/yubihsm.pc.in ${CMAKE_CURRENT_BINARY_DIR}/yubihsm.pc @ONLY)
Expand Down
41 changes: 41 additions & 0 deletions lib/yubihsm.c
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@

#include "../common/insecure_memzero.h"
#include "../ykhsmauth/ykhsmauth.h"
#include "../common/data_compress.h"

#define STATIC_USB_BACKEND "usb"
#define STATIC_HTTP_BACKEND "http"
Expand Down Expand Up @@ -3366,6 +3367,46 @@ yh_rc yh_util_get_opaque(yh_session *session, uint16_t object_id, uint8_t *out,
return YHR_SUCCESS;
}

yh_rc yh_util_import_opaque_ex(yh_session *session, uint16_t *object_id,
const char *label, uint16_t domains,
const yh_capabilities *capabilities,
yh_algorithm algorithm, bool compress,
const uint8_t *in, size_t in_len) {
#ifndef USE_CERT_COMPRESS
if(compress) {
DBG_ERR("Compression not supported");
return YHR_INVALID_PARAMETERS;
}
#endif

if(compress && algorithm != YH_ALGO_OPAQUE_X509_CERTIFICATE) {
DBG_ERR("Compression of non-X509Cerificate is not supported");
return YHR_INVALID_PARAMETERS;
}

if(compress) {
if (in == NULL) {
DBG_ERR("%s", yh_strerror(YHR_INVALID_PARAMETERS));
return YHR_INVALID_PARAMETERS;
}

uint8_t compressed_data[YH_MSG_BUF_SIZE] = {0};
size_t compressed_data_len = sizeof(compressed_data);

if (compress_data((unsigned char *) in, in_len, compressed_data,
&compressed_data_len) != 0) {
fprintf(stderr, "Couldn't compress certificate\n");
return YHR_GENERIC_ERROR;
}
return yh_util_import_opaque(session, object_id, label, domains,
capabilities, algorithm, compressed_data,
compressed_data_len);
} else {
return yh_util_import_opaque(session, object_id, label, domains,
capabilities, algorithm, in, in_len);
}
}

yh_rc yh_util_import_opaque(yh_session *session, uint16_t *object_id,
const char *label, uint16_t domains,
const yh_capabilities *capabilities,
Expand Down
34 changes: 27 additions & 7 deletions lib/yubihsm.h
Original file line number Diff line number Diff line change
Expand Up @@ -529,10 +529,6 @@ typedef enum {
YH_ALGO_AES_CBC = 54,
/// aes-kwp
YH_ALGO_AES_KWP = 55,
#ifdef USE_CERT_COMPRESS
/// Compressed certificate
YH_ALGO_OPAQUE_X509_COMPRESSED = 128,
#endif
} yh_algorithm;

/**
Expand Down Expand Up @@ -752,9 +748,6 @@ static const struct {
{"mgf1-sha512", YH_ALGO_MGF1_SHA512},
{"opaque-data", YH_ALGO_OPAQUE_DATA},
{"opaque-x509-certificate", YH_ALGO_OPAQUE_X509_CERTIFICATE},
#ifdef USE_CERT_COMPRESS
{"opaque-x509-compressed", YH_ALGO_OPAQUE_X509_COMPRESSED},
#endif
{"rsa-oaep-sha1", YH_ALGO_RSA_OAEP_SHA1},
{"rsa-oaep-sha256", YH_ALGO_RSA_OAEP_SHA256},
{"rsa-oaep-sha384", YH_ALGO_RSA_OAEP_SHA384},
Expand Down Expand Up @@ -2221,6 +2214,33 @@ yh_rc yh_util_set_log_index(yh_session *session, uint16_t index);
yh_rc yh_util_get_opaque(yh_session *session, uint16_t object_id, uint8_t *out,
size_t *out_len);

/**
* Import an #YH_OPAQUE object into the device
*
* @param session Authenticated session to use
* @param object_id Object ID of the Opaque object. 0 if the Object ID should be
*generated by the device
* @param label Label of the Opaque object. Maximum length is #YH_OBJ_LABEL_LEN
* @param domains Domains the Opaque object will be operating within. See
*#yh_string_to_domains()
* @param capabilities Capabilities of the Opaque object. See
*#yh_string_to_capabilities()
* @param algorithm Algorithm of the Opaque object
* @param compress If true, compress cert data before import
* @param in the Opaque object to import
* @param in_len Length of the Opaque object to import
*
* @return #YHR_SUCCESS if successful.
* #YHR_INVALID_PARAMETERS if input parameters are NULL or
*<tt>in_len</tt> is too big.
* See #yh_rc for other possible errors
**/
yh_rc yh_util_import_opaque_ex(yh_session *session, uint16_t *object_id,
const char *label, uint16_t domains,
const yh_capabilities *capabilities,
yh_algorithm algorithm, bool compress,
const uint8_t *in, size_t in_len);

/**
* Import an #YH_OPAQUE object into the device
*
Expand Down
1 change: 1 addition & 0 deletions src/cmdline.ggo
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,7 @@ option "attestation-id" - "Attestation ID" int optional
option "log-index" - "Log index" int optional
option "opt-name" - "Device option name" string optional
option "opt-value" - "Device option value" string optional
option "compress" - "Compress a large certificate before import" flag off

option "in" - "Input data (filename)" string optional default="-"
option "out" - "Output data (filename)" string optional default="-"
Expand Down
48 changes: 14 additions & 34 deletions src/commands.c
Original file line number Diff line number Diff line change
Expand Up @@ -917,9 +917,9 @@ int yh_com_get_opaque(yubihsm_context *ctx, Argument *argv, cmd_format in_fmt,
const unsigned char *ptr = response;
X509 *x509 = d2i_X509(NULL, &ptr, response_len);
if (!x509) {
fprintf(stderr, "Failed parsing x509 information.\n");
fprintf(stderr, "Failed parsing x509 information. Possibly compressed certificate\n");
#ifdef USE_CERT_COMPRESS
fprintf(stderr, "Trying to parse it as compressed certificate\n");
fprintf(stdio, "Trying to parse it as compressed certificate\n");
uint8_t certdata[4096] = {0};
size_t certdata_len = sizeof(certdata);
if(uncompress_data(response, response_len, certdata, &certdata_len) != 0) {
Expand Down Expand Up @@ -2287,16 +2287,15 @@ int yh_com_put_authentication_asym(yubihsm_context *ctx, Argument *argv,
// arg 3: w:domains
// arg 4: c:capabilities
// arg 5: a:algorithm
// arg 6: i:datafile
// arg 6: b:compress
// arg 7: i:datafile
int yh_com_put_opaque(yubihsm_context *ctx, Argument *argv, cmd_format in_fmt,
cmd_format fmt) {

UNUSED(ctx);
UNUSED(fmt);
unsigned char buf[YH_MSG_BUF_SIZE], *data = argv[6].x;
size_t len = argv[6].len;

X509 *cert = NULL;
unsigned char buf[YH_MSG_BUF_SIZE], *data = argv[7].x;
size_t len = argv[7].len;

if (in_fmt == fmt_PEM) {
// Decode X.509 Certificate regardless of algorithm in case fmt_PEM is
Expand All @@ -2306,7 +2305,7 @@ int yh_com_put_opaque(yubihsm_context *ctx, Argument *argv, cmd_format in_fmt,
fprintf(stderr, "Couldn't wrap PEM-encoded certificate data\n");
return 0;
}
cert = PEM_read_bio_X509(bio, NULL, NULL, NULL);
X509 *cert = PEM_read_bio_X509(bio, NULL, NULL, NULL);
if (!cert) {
fprintf(stderr, "Couldn't parse PEM-encoded certificate\n");
BIO_free(bio);
Expand All @@ -2322,40 +2321,21 @@ int yh_com_put_opaque(yubihsm_context *ctx, Argument *argv, cmd_format in_fmt,
data = buf;
i2d_X509(cert, &data);
data = buf;
}

if (!cert && (argv[5].a == YH_ALGO_OPAQUE_X509_CERTIFICATE
#ifdef USE_CERT_COMPRESS
|| argv[5].a == YH_ALGO_OPAQUE_X509_COMPRESSED
#endif
)) {
X509_free(cert);
} else if (argv[5].a == YH_ALGO_OPAQUE_X509_CERTIFICATE) {
// Enforce valid X.509 certificate
const unsigned char *p = data;
cert = d2i_X509(NULL, &p, len);
X509 *cert = d2i_X509(NULL, &p, len);
if (!cert) {
fprintf(stderr, "Couldn't parse DER-encoded certificate\n");
return 0;
}
X509_free(cert);
}

#ifdef USE_CERT_COMPRESS
if (cert && argv[5].a == YH_ALGO_OPAQUE_X509_COMPRESSED) {

uint8_t compressed_data[YH_MSG_BUF_SIZE] = {0};
size_t compressed_data_len = sizeof(compressed_data);

if (compress_data(data, len, compressed_data, &compressed_data_len) != 0) {
fprintf(stderr, "Couldn't compress certificate\n");
return 0;
}
memcpy(data, compressed_data, compressed_data_len);
len = compressed_data_len;
}
#endif
X509_free(cert);

yh_rc yrc = yh_util_import_opaque(argv[0].e, &argv[1].w, argv[2].s, argv[3].w,
&argv[4].c, argv[5].a, data, len);
yh_rc yrc =
yh_util_import_opaque_ex(argv[0].e, &argv[1].w, argv[2].s, argv[3].w,
&argv[4].c, argv[5].a, argv[6].b, data, len);
if (yrc != YHR_SUCCESS) {
fprintf(stderr, "Failed to store opaque object: %s\n", yh_strerror(yrc));
return -1;
Expand Down
14 changes: 8 additions & 6 deletions src/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -483,11 +483,11 @@ static void create_command_list(CommandList *c) {
fmt_PEM, fmt_nofmt,
"Store an asymmetric authentication key", NULL,
NULL});
register_subcommand(*c, (Command){"opaque", yh_com_put_opaque,
"e:session,w:object_id,s:label,d:domains,c:"
"capabilities,a:algorithm,i:data=-",
fmt_binary, fmt_nofmt,
"Store an opaque object", NULL, NULL});
register_subcommand(
*c, (Command){"opaque", yh_com_put_opaque,
"e:session,w:object_id,s:label,d:domains,c:"
"capabilities,a:algorithm,b:compress=0,i:data=-",
fmt_binary, fmt_nofmt, "Store an opaque object", NULL, NULL});
register_subcommand(*c,
(Command){"option", yh_com_put_option,
"e:session,o:option,i:data", fmt_hex, fmt_nofmt,
Expand Down Expand Up @@ -2646,7 +2646,9 @@ int main(int argc, char *argv[]) {
yrc = yh_string_to_algo(args_info.algorithm_arg, &arg[5].a);
LIB_SUCCEED_OR_DIE(yrc, "Unable to parse algorithm: ");

if (get_input_data(args_info.in_arg, &arg[6].x, &arg[6].len,
arg[6].b = args_info.compress_given;

if (get_input_data(args_info.in_arg, &arg[7].x, &arg[7].len,
g_in_fmt == fmt_nofmt ? fmt_binary : g_in_fmt) ==
false) {
fprintf(stderr, "Failed to get input data\n");
Expand Down

0 comments on commit e77dba6

Please sign in to comment.