Expand Up
@@ -29,39 +29,34 @@
// THE POSSIBILITY OF SUCH DAMAGE.
//**********************************************************************;
#include <stdarg.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <limits.h>
#include <ctype.h>
#include <getopt.h>
#include <sapi/tpm20.h>
#include "tpm2_options.h"
#include "files.h"
#include "log.h"
#include "tpm2_util.h"
#include "tpm_hash.h"
#include "tpm2_alg_util.h"
#include "tpm_hash.h"
#include "tpm2_options.h"
#include "tpm2_tool.h"
#include "tpm2_util.h"
typedef struct tpm2_verifysig_ctx tpm2_verifysig_ctx ;
struct tpm2_verifysig_ctx {
union {
struct {
uint8_t key_handle :1 ;
uint8_t digest :1 ;
uint8_t halg :1 ;
uint8_t msg :1 ;
uint8_t raw :1 ;
uint8_t sig :1 ;
uint8_t ticket :1 ;
uint8_t key_context :1 ;
UINT8 key_handle :1 ;
UINT8 digest :1 ;
UINT8 halg :1 ;
UINT8 msg :1 ;
UINT8 raw :1 ;
UINT8 sig :1 ;
UINT8 ticket :1 ;
UINT8 key_context :1 ;
};
uint8_t all ;
UINT8 all ;
} flags ;
TPMI_ALG_HASH halg ;
TPM2B_DIGEST msgHash ;
Expand All
@@ -71,10 +66,15 @@ struct tpm2_verifysig_ctx {
char * sig_file_path ;
char * out_file_path ;
char * context_key_file_path ;
TSS2_SYS_CONTEXT * sapi_context ;
};
static bool verify_signature (tpm2_verifysig_ctx * ctx ) {
tpm2_verifysig_ctx ctx = {
.halg = TPM_ALG_SHA1 ,
.msgHash = TPM2B_TYPE_INIT (TPM2B_DIGEST , buffer ),
};
static bool verify_signature (TSS2_SYS_CONTEXT * sapi_context ) {
UINT32 rval ;
TPMT_TK_VERIFIED validation ;
Expand All
@@ -88,19 +88,20 @@ static bool verify_signature(tpm2_verifysig_ctx *ctx) {
sessionsDataOut .rspAuthsCount = 1 ;
UINT16 i ;
for (i = 0 ; i < ctx -> msgHash .t .size ; i ++ )
printf ("%02x " , ctx -> msgHash .t .buffer [i ]);
printf ("\n" );
for (i = 0 ; i < ctx .msgHash .t .size ; i ++ ) {
tpm2_tool_output ("%02x " , ctx .msgHash .t .buffer [i ]);
}
tpm2_tool_output ("\n" );
rval = Tss2_Sys_VerifySignature (ctx -> sapi_context , ctx -> keyHandle , NULL ,
& ctx -> msgHash , & ctx -> signature , & validation , & sessionsDataOut );
rval = Tss2_Sys_VerifySignature (sapi_context , ctx . keyHandle , NULL ,
& ctx . msgHash , & ctx . signature , & validation , & sessionsDataOut );
if (rval != TPM_RC_SUCCESS ) {
LOG_ERR ("Tss2_Sys_VerifySignature failed, error code: 0x%x" , rval );
return false;
}
/* TODO fix serialization */
return files_save_bytes_to_file (ctx -> out_file_path , (UINT8 * ) & validation ,
return files_save_bytes_to_file (ctx . out_file_path , (UINT8 * ) & validation ,
sizeof (validation ));
}
Expand Down
Expand Up
@@ -132,72 +133,86 @@ static TPM2B *message_from_file(const char *msg_file_path) {
return msg ;
}
static bool generate_signature (tpm2_verifysig_ctx * ctx ) {
static bool generate_signature (void ) {
UINT16 size ;
UINT8 * buffer ;
if (ctx -> flags .raw ) {
ctx -> signature .sigAlg = TPM_ALG_RSASSA ;
ctx -> signature .signature .rsassa .hash = ctx -> halg ;
ctx -> signature .signature .rsassa .sig .t .size =
sizeof (ctx -> signature .signature .rsassa .sig ) - 2 ;
if (ctx . flags .raw ) {
ctx . signature .sigAlg = TPM_ALG_RSASSA ;
ctx . signature .signature .rsassa .hash = ctx . halg ;
ctx . signature .signature .rsassa .sig .t .size =
sizeof (ctx . signature .signature .rsassa .sig ) - 2 ;
buffer = ctx -> signature .signature .rsassa .sig .t .buffer ;
size = ctx -> signature .signature .rsassa .sig .t .size ;
buffer = ctx . signature .signature .rsassa .sig .t .buffer ;
size = ctx . signature .signature .rsassa .sig .t .size ;
} else {
size = sizeof (ctx -> signature );
buffer = (UINT8 * ) & ctx -> signature ;
size = sizeof (ctx . signature );
buffer = (UINT8 * ) & ctx . signature ;
}
bool result = files_load_bytes_from_path (ctx -> sig_file_path , buffer , & size );
bool result = files_load_bytes_from_path (ctx . sig_file_path , buffer , & size );
if (!result ) {
LOG_ERR ("Could not create %s signature from file: \"%s\"" ,
ctx -> flags .raw ? "raw" : "\0" , ctx -> sig_file_path );
ctx . flags .raw ? "raw" : "\0" , ctx . sig_file_path );
}
return result ;
}
static bool init (tpm2_verifysig_ctx * ctx ) {
static bool init (TSS2_SYS_CONTEXT * sapi_context ) {
/* check flags for mismatches */
if (ctx .flags .digest && (ctx .flags .msg || ctx .flags .halg )) {
LOG_ERR (
"Cannot specify --digest (-D) and ( --msg (-m) or --halg (-g) )" );
return false;
}
if (!((ctx .flags .key_handle || ctx .flags .key_context ) && ctx .flags .sig
&& ctx .flags .ticket )) {
LOG_ERR (
"--keyHandle (-k) or --keyContext (-c) and --sig (-s) and --ticket (-t) must be specified" );
return false;
}
TPM2B * msg = NULL ;
bool return_value = false;
if (ctx -> flags .msg ) {
msg = message_from_file (ctx -> msg_file_path );
if (ctx . flags .msg ) {
msg = message_from_file (ctx . msg_file_path );
if (!msg ) {
/* message_from_file() logs specific error no need to here */
return false;
}
}
if (ctx -> flags .sig ) {
bool res = generate_signature (ctx );
if (ctx . flags .sig ) {
bool res = generate_signature ();
if (!res ) {
goto err ;
}
}
if (ctx -> flags .key_context ) {
bool result = files_load_tpm_context_from_file (ctx -> sapi_context , & ctx -> keyHandle ,
ctx -> context_key_file_path );
if (ctx . flags .key_context ) {
bool result = files_load_tpm_context_from_file (sapi_context , & ctx . keyHandle ,
ctx . context_key_file_path );
if (!result ) {
goto err ;
}
}
/* If no digest is specified, compute it */
if (!ctx -> flags .digest ) {
if (!ctx -> flags .msg ) {
if (!ctx . flags .digest ) {
if (!ctx . flags .msg ) {
/*
* This is a redundant check since main() checks this case, but we'll add it here to silence any
* complainers.
*/
LOG_ERR ("No digest set and no message file to compute from, cannot compute message hash!" );
goto err ;
}
int rc = tpm_hash_compute_data (ctx -> sapi_context , ctx -> halg ,
TPM_RH_NULL , msg -> buffer , msg -> size , & ctx -> msgHash , NULL );
int rc = tpm_hash_compute_data (sapi_context , ctx . halg ,
TPM_RH_NULL , msg -> buffer , msg -> size , & ctx . msgHash , NULL );
if (rc ) {
LOG_ERR ("Compute message hash failed!" );
goto err ;
Expand All
@@ -208,12 +223,72 @@ static bool init(tpm2_verifysig_ctx *ctx) {
err :
free (msg );
return return_value ;
}
static bool on_option (char key , char * value ) {
switch (key ) {
case 'k' : {
bool res = tpm2_util_string_to_uint32 (value , & ctx .keyHandle );
if (!res ) {
LOG_ERR ("Unable to convert key handle, got: \"%s\"" , value );
return false;
}
ctx .flags .key_handle = 1 ;
}
break ;
case 'g' : {
ctx .halg = tpm2_alg_util_from_optarg (value );
if (ctx .halg == TPM_ALG_ERROR ) {
LOG_ERR ("Unable to convert algorithm, got: \"%s\"" , value );
return false;
}
ctx .flags .halg = 1 ;
}
break ;
case 'm' : {
ctx .msg_file_path = value ;
ctx .flags .msg = 1 ;
}
break ;
case 'D' : {
UINT16 size = sizeof (ctx .msgHash );
if (!files_load_bytes_from_path (value , (UINT8 * ) & ctx .msgHash , & size )) {
LOG_ERR ("Could not load digest from file!" );
return false;
}
ctx .flags .digest = 1 ;
}
break ;
case 'r' :
ctx .flags .raw = 1 ;
break ;
case 's' :
ctx .sig_file_path = value ;
ctx .flags .sig = 1 ;
break ;
case 't' :
ctx .out_file_path = value ;
if (files_does_file_exist (ctx .out_file_path )) {
return false;
}
ctx .flags .ticket = 1 ;
break ;
case 'c' :
ctx .context_key_file_path = value ;
ctx .flags .key_context = 1 ;
break ;
/* no default */
}
return true;
}
static bool handle_options_and_init ( int argc , char * argv [], tpm2_verifysig_ctx * ctx ) {
bool tpm2_tool_onstart ( tpm2_options * * opts ) {
const char * optstring = "k:g:m:D:rs:t:c:" ;
const struct option long_options [] = {
const struct option topts [] = {
{ "keyHandle" , 1 , NULL , 'k' },
{ "digest" , 1 , NULL , 'D' },
{ "halg" , 1 , NULL , 'g' },
Expand All
@@ -225,121 +300,27 @@ static bool handle_options_and_init(int argc, char *argv[], tpm2_verifysig_ctx *
{ NULL , 0 , NULL , '\0' }
};
if (argc == 1 ) {
LOG_ERR ("Invalid usage. Try --help for help." );
return false;
}
int opt ;
while ((opt = getopt_long (argc , argv , optstring , long_options , NULL )) != -1 ) {
switch (opt ) {
case 'k' : {
bool res = tpm2_util_string_to_uint32 (optarg , & ctx -> keyHandle );
if (!res ) {
LOG_ERR ("Unable to convert key handle, got: \"%s\"" , optarg );
return false;
}
ctx -> flags .key_handle = 1 ;
}
break ;
case 'g' : {
ctx -> halg = tpm2_alg_util_from_optarg (optarg );
if (ctx -> halg == TPM_ALG_ERROR ) {
LOG_ERR ("Unable to convert algorithm, got: \"%s\"" , optarg );
return false;
}
ctx -> flags .halg = 1 ;
}
break ;
case 'm' : {
ctx -> msg_file_path = optarg ;
ctx -> flags .msg = 1 ;
}
break ;
case 'D' : {
UINT16 size = sizeof (ctx -> msgHash );
if (!files_load_bytes_from_path (optarg , (UINT8 * ) & ctx -> msgHash , & size )) {
LOG_ERR ("Could not load digest from file!" );
return false;
}
ctx -> flags .digest = 1 ;
}
break ;
case 'r' :
ctx -> flags .raw = 1 ;
break ;
case 's' :
ctx -> sig_file_path = optarg ;
ctx -> flags .sig = 1 ;
break ;
case 't' :
ctx -> out_file_path = optarg ;
if (files_does_file_exist (ctx -> out_file_path )) {
return false;
}
ctx -> flags .ticket = 1 ;
break ;
case 'c' :
ctx -> context_key_file_path = optarg ;
ctx -> flags .key_context = 1 ;
break ;
case ':' :
LOG_ERR ("Argument %c needs a value!" , optopt );
break ;
case '?' :
LOG_ERR ("Unknown Argument: %c" , optopt );
break ;
/* no default */
}
};
/* check flags for mismatches */
if (ctx -> flags .digest && (ctx -> flags .msg || ctx -> flags .halg )) {
LOG_ERR (
"Cannot specify --digest (-D) and ( --msg (-m) or --halg (-g) )" );
return false;
}
if (!((ctx -> flags .key_handle || ctx -> flags .key_context ) && ctx -> flags .sig
&& ctx -> flags .ticket )) {
LOG_ERR (
"--keyHandle (-k) or --keyContext (-c) and --sig (-s) and --ticket (-t) must be specified" );
return false;
}
* opts = tpm2_options_new ("k:g:m:D:rs:t:c:" , ARRAY_LEN (topts ), topts ,
on_option , NULL );
/* initialize and process */
return init (ctx );
return * opts != NULL ;
}
int execute_tool (int argc , char * argv [], char * envp [], common_opts_t * opts ,
TSS2_SYS_CONTEXT * sapi_context ) {
(void ) opts ;
(void ) envp ;
int tpm2_tool_onrun (TSS2_SYS_CONTEXT * sapi_context , tpm2_option_flags flags ) {
int normalized_return_code = 1 ;
UNUSED ( flags ) ;
tpm2_verifysig_ctx ctx = {
.flags = { .all = 0 },
.halg = TPM_ALG_SHA1 ,
.msgHash = TPM2B_TYPE_INIT (TPM2B_DIGEST , buffer ),
.sig_file_path = NULL ,
.msg_file_path = NULL ,
.out_file_path = NULL ,
.context_key_file_path = NULL ,
.sapi_context = sapi_context
};
bool res = handle_options_and_init (argc , argv , & ctx );
/* initialize and process */
bool res = init (sapi_context );
if (!res ) {
return normalized_return_code ;
return 1 ;
}
res = verify_signature (& ctx );
res = verify_signature (sapi_context );
if (!res ) {
LOG_ERR ("Verify signature failed!" );
return normalized_return_code ;
return 1 ;
}
return 0 ;
Expand Down