Skip to content

Commit

Permalink
Merge pull request #124 from xaptum/zanebeckwith/fix-x509-sigs
Browse files Browse the repository at this point in the history
Fix (and restructure) X.509 certificate creation
  • Loading branch information
zanebeckwith authored Dec 14, 2020
2 parents 7da6e3e + 7ced9a3 commit 83c8558
Show file tree
Hide file tree
Showing 16 changed files with 547 additions and 761 deletions.
4 changes: 3 additions & 1 deletion CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ option(USE_TPM "use a TPM" ON)
option(BUILD_SHARED_LIBS "Build as a shared library" ON)
option(BUILD_STATIC_LIBS "Build as a static library" OFF)
option(BUILD_TOOL "Build XTT tool" ON)
option(TEST_USE_OPENSSL "Run tests that require an OpenSSL installation" ON)

find_package(ecdaa 1.0.0 REQUIRED QUIET)
find_package(sodium 1.0.11 REQUIRED QUIET)
Expand Down Expand Up @@ -57,7 +58,8 @@ set(XTT_SRCS
src/util/root.c
src/util/generate_server_certificate.c
src/util/generate_x509_certificate.c
src/util/internal/asn1.c
src/util/internal/cert_x509.c
src/util/internal/key_asn1.c
src/internal/byte_utils.c
src/internal/key_derivation.c
src/internal/crypto_utils.c
Expand Down
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,7 @@ The following CMake configuration options are supported.
| BUILD_SHARED_LIBS | ON, OFF | ON | Build shared libraries. |
| BUILD_STATIC_LIBS | ON, OFF | OFF | Build static libraries. |
| BUILD_TESTING | ON, OFF | ON | Build the test suite. |
| TEST_USE_OPENSSL | ON, OFF | ON | Run tests that require an OpenSSL installation. |
| STATIC_SUFFIX | <string> | <none> | Appends a suffix to the static lib name. |

### Installing
Expand Down
18 changes: 9 additions & 9 deletions include/xtt/util/asn1.h
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
/******************************************************************************
*
* Copyright 2017 Xaptum, Inc.
* Copyright 2017-2020 Xaptum, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
Expand Down Expand Up @@ -32,26 +32,26 @@
extern "C" {
#endif

#define XTT_X509_CERTIFICATE_LENGTH 352
size_t xtt_x509_certificate_length(void);
#define XTT_X509_CERTIFICATE_MAX_LENGTH 360
size_t xtt_x509_certificate_max_length(void);

#define XTT_ASN1_PRIVATE_KEY_LENGTH 121
size_t xtt_asn1_private_key_length(void);


/*
* Creates a x509 certificate from pub_key_in, priv_key_in, and common_name
* and writes the certificate into certificate_out
* and writes the certificate into certificate_out (and its length into certificate_length_out)
*
* Returns:
* 0 on success
* CERT_CREATION_ERROR on failure
*/
int xtt_x509_from_ecdsap256_keypair(const xtt_ecdsap256_pub_key *pub_key_in,
const xtt_ecdsap256_priv_key *priv_key_in,
const xtt_identity_type *common_name,
unsigned char *certificate_out,
size_t certificate_out_length);
const xtt_ecdsap256_priv_key *priv_key_in,
const xtt_identity_type *common_name,
unsigned char *certificate_out,
size_t *certificate_length_out);

#ifdef USE_TPM
/*
Expand All @@ -62,7 +62,7 @@ int xtt_x509_from_ecdsap256_TPM(const xtt_ecdsap256_pub_key *pub_key_in,
TSS2_TCTI_CONTEXT *tcti_context,
const xtt_identity_type *common_name,
unsigned char *certificate_out,
size_t certificate_out_length);
size_t *certificate_length_out);
#endif

/*
Expand Down
113 changes: 51 additions & 62 deletions src/util/asn1.c
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
/******************************************************************************
*
* Copyright 2017 Xaptum, Inc.
* Copyright 2017-2020 Xaptum, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
Expand All @@ -18,7 +18,8 @@

#include <xtt/util/asn1.h>
#include <xtt/util/util_errors.h>
#include "internal/asn1.h"
#include "internal/cert_x509.h"
#include "internal/key_asn1.h"

#include <xtt/crypto_wrapper.h>
#include <xtt/crypto_types.h>
Expand All @@ -30,9 +31,9 @@
#define XTT_ECDSAP256_PRIVATE_KEY_OFFSET 7
#define XTT_ECDSAP256_PUBLIC_KEY_OFFSET 56

size_t xtt_x509_certificate_length(void)
size_t xtt_x509_certificate_max_length(void)
{
return XTT_X509_CERTIFICATE_LENGTH;
return XTT_X509_CERTIFICATE_MAX_LENGTH;
}

size_t xtt_asn1_private_key_length(void)
Expand All @@ -46,30 +47,26 @@ int xtt_x509_from_ecdsap256_TPM(const xtt_ecdsap256_pub_key *pub_key_in,
TSS2_TCTI_CONTEXT *tcti_context,
const xtt_identity_type *common_name,
unsigned char *certificate_out,
size_t certificate_out_length)
size_t *certificate_length_out)
{
assert(XTT_X509_CERTIFICATE_LENGTH == get_certificate_length());

unsigned char *pub_key_location;
unsigned char *signature_location;
unsigned char *signature_input_location;
size_t signature_input_length;
xtt_identity_string common_name_as_string;

if (certificate_out_length < XTT_X509_CERTIFICATE_LENGTH)
return CERT_CREATION_ERROR;

int convert_ret = xtt_identity_to_string(common_name, &common_name_as_string);
if (0 != convert_ret)
if (*certificate_length_out < XTT_X509_CERTIFICATE_MAX_LENGTH)
return CERT_CREATION_ERROR;

build_x509_skeleton(certificate_out, &pub_key_location, &signature_location, &signature_input_location, &signature_input_length, common_name_as_string.data);
xtt_identity_string common_name_as_string = {};
if (0 != xtt_identity_to_string(common_name, &common_name_as_string))
return CERT_CREATION_ERROR;

memcpy(pub_key_location, pub_key_in->data, sizeof(xtt_ecdsap256_pub_key));
unsigned char *to_be_signed_location = NULL;
size_t to_be_signed_length = 0;
build_x509_preamble(&common_name_as_string,
pub_key_in,
certificate_out,
&to_be_signed_location,
&to_be_signed_length);

TPM2B_DIGEST hash = {};
struct xtt_crypto_hmac xtt_hash = {};
if (0 != xtt_crypto_hash_sha256(&xtt_hash, signature_input_location, signature_input_length))
if (0 != xtt_crypto_hash_sha256(&xtt_hash, to_be_signed_location, to_be_signed_length))
return CERT_CREATION_ERROR;
memcpy(hash.buffer, &xtt_hash.buf, sizeof(xtt_crypto_sha256));
hash.size = xtt_hash.len;
Expand All @@ -81,67 +78,59 @@ int xtt_x509_from_ecdsap256_TPM(const xtt_ecdsap256_pub_key *pub_key_in,
&tpm_signature))
return CERT_CREATION_ERROR;

memcpy(signature_location,
&tpm_signature.signature.ecdsa.signatureR.buffer[0],
tpm_signature.signature.ecdsa.signatureR.size);
memcpy(signature_location + tpm_signature.signature.ecdsa.signatureR.size,
tpm_signature.signature.ecdsa.signatureS.buffer,
tpm_signature.signature.ecdsa.signatureS.size);
append_x509_signature(&tpm_signature.signature.ecdsa.signatureR.buffer[0],
&tpm_signature.signature.ecdsa.signatureS.buffer[0],
certificate_out);

*certificate_length_out = certificate_length(certificate_out);

return 0;
}
#endif

int xtt_x509_from_ecdsap256_keypair(const xtt_ecdsap256_pub_key *pub_key_in,
const xtt_ecdsap256_priv_key *priv_key_in,
const xtt_identity_type *common_name,
unsigned char *certificate_out,
size_t certificate_out_length)
const xtt_ecdsap256_priv_key *priv_key_in,
const xtt_identity_type *common_name,
unsigned char *certificate_out,
size_t *certificate_length_out)
{
assert(XTT_X509_CERTIFICATE_LENGTH == get_certificate_length());

unsigned char *pub_key_location;
unsigned char *signature_location;
unsigned char *signature_input_location;
size_t signature_input_length;
xtt_identity_string common_name_as_string;

if (certificate_out_length < XTT_X509_CERTIFICATE_LENGTH)
return CERT_CREATION_ERROR;
if (*certificate_length_out < XTT_X509_CERTIFICATE_MAX_LENGTH)
return CERT_CREATION_ERROR;

int convert_ret = xtt_identity_to_string(common_name, &common_name_as_string);
if (0 != convert_ret)
xtt_identity_string common_name_as_string = {};
if (0 != xtt_identity_to_string(common_name, &common_name_as_string))
return CERT_CREATION_ERROR;

build_x509_skeleton(certificate_out, &pub_key_location, &signature_location, &signature_input_location, &signature_input_length, common_name_as_string.data);
unsigned char *to_be_signed_location = NULL;
size_t to_be_signed_length = 0;
build_x509_preamble(&common_name_as_string,
pub_key_in,
certificate_out,
&to_be_signed_location,
&to_be_signed_length);

unsigned char combined_sig[sizeof(xtt_ecdsap256_signature)] = {};
if (0 != xtt_crypto_sign_ecdsap256(combined_sig,
to_be_signed_location,
to_be_signed_length,
priv_key_in))
return CERT_CREATION_ERROR;

memcpy(pub_key_location, pub_key_in->data, sizeof(xtt_ecdsap256_pub_key));
append_x509_signature(&combined_sig[0],
&combined_sig[P256_BIGNUM_SIZE],
certificate_out);

int sign_ret = xtt_crypto_sign_ecdsap256(signature_location, signature_input_location, signature_input_length, priv_key_in);
*certificate_length_out = certificate_length(certificate_out);

if (0 != sign_ret) {
return CERT_CREATION_ERROR;
} else {
return 0;
}
return 0;
}

int xtt_write_ecdsap256_keypair(xtt_ecdsap256_pub_key *pub_key, xtt_ecdsap256_priv_key *priv_key, const char *keypair_file)
{
// 1) Create ASN.1 wrapped key pair
unsigned char keypair[XTT_ASN1_PRIVATE_KEY_LENGTH] = {0};
assert(XTT_ASN1_PRIVATE_KEY_LENGTH == get_asn1privatekey_length());

unsigned char *privkey_location;
unsigned char *pubkey_location;

build_asn1_key_skeleton(keypair, &privkey_location, &pubkey_location);

memcpy(privkey_location, priv_key->data, sizeof(xtt_ecdsap256_priv_key));

memcpy(pubkey_location, pub_key->data, sizeof(xtt_ecdsap256_pub_key));
build_asn1_key(pub_key, priv_key, keypair);

// 2) Write key pair to file
int save_ret = xtt_save_key_to_file(keypair, XTT_ASN1_PRIVATE_KEY_LENGTH, keypair_file);
if (save_ret < 0) {
return SAVE_TO_FILE_ERROR;
Expand Down
7 changes: 4 additions & 3 deletions src/util/generate_x509_certificate.c
Original file line number Diff line number Diff line change
Expand Up @@ -49,13 +49,14 @@ int xtt_generate_x509_certificate(const char *keypair_filename, const char *id_f
}

// 3) Create certificate and save to file.
unsigned char cert_buf[XTT_X509_CERTIFICATE_LENGTH] = {0};
ret = xtt_x509_from_ecdsap256_keypair(&pub, &priv, &id, cert_buf, sizeof(cert_buf));
unsigned char cert_buf[XTT_X509_CERTIFICATE_MAX_LENGTH] = {0};
size_t cert_len = sizeof(cert_buf);
ret = xtt_x509_from_ecdsap256_keypair(&pub, &priv, &id, cert_buf, &cert_len);
if (0 != ret) {
return CERT_CREATION_ERROR;
}

write_ret = xtt_save_cert_to_file(cert_buf, sizeof(cert_buf), certificate_filename);
write_ret = xtt_save_cert_to_file(cert_buf, cert_len, certificate_filename);
if (write_ret < 0) {
return SAVE_TO_FILE_ERROR;
}
Expand Down
Loading

0 comments on commit 83c8558

Please sign in to comment.