File: tpm2_getcommandauditdigest.c

package info (click to toggle)
tpm2-tools 5.7-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 5,988 kB
  • sloc: ansic: 45,737; sh: 14,915; xml: 8,342; makefile: 610; python: 51
file content (259 lines) | stat: -rw-r--r-- 7,085 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
/* SPDX-License-Identifier: BSD-3-Clause */

#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#include "files.h"
#include "log.h"
#include "tpm2.h"
#include "tpm2_alg_util.h"
#include "tpm2_convert.h"
#include "tpm2_openssl.h"
#include "tpm2_tool.h"

typedef struct tpm_getcommandauditdigest_ctx tpm_getcommandauditdigest_ctx;
struct tpm_getcommandauditdigest_ctx {
    struct {
        const char *ctx_path;
        const char *auth_str;
        tpm2_loaded_object object;
    } key;

    struct {
        const char *ctx_path;
        const char *auth_str;
        tpm2_loaded_object object;
    } endorsement_hierarchy;

    char *signature_path;
    char *message_path;
    tpm2_convert_sig_fmt sig_format;
    TPMI_ALG_HASH sig_hash_algorithm;
    TPMI_ALG_SIG_SCHEME sig_scheme;
    TPM2B_DATA qualification_data;
    TPM2B_ATTEST *audit_info;
    TPMT_SIGNATURE *signature;
    TPMT_SIG_SCHEME in_scheme;
};

static tpm_getcommandauditdigest_ctx ctx = {
    .sig_hash_algorithm = TPM2_ALG_NULL,
    .sig_scheme = TPM2_ALG_NULL,
    .qualification_data = TPM2B_EMPTY_INIT,
    .endorsement_hierarchy = {
        .ctx_path = "e"
    },
    .in_scheme = {
        .scheme = TPM2_ALG_NULL,
    }
};

static bool on_option(char key, char *value) {

    switch (key) {
    case 'P':
        ctx.endorsement_hierarchy.auth_str = value;
        break;
    case 'c':
        ctx.key.ctx_path = value;
        break;
    case 'p':
        ctx.key.auth_str = value;
        break;
    case 'q':
        ctx.qualification_data.size = sizeof(ctx.qualification_data.buffer);
        return tpm2_util_bin_from_hex_or_file(value, &ctx.qualification_data.size,
                ctx.qualification_data.buffer);
        break;
    case 's':
        ctx.signature_path = value;
        break;
    case 'm':
        ctx.message_path = value;
        break;
    case 'f':
        ctx.sig_format = tpm2_convert_sig_fmt_from_optarg(value);

        if (ctx.sig_format == signature_format_err) {
            return false;
        }
        break;
    case 'g':
        ctx.sig_hash_algorithm = tpm2_alg_util_from_optarg(value,
                tpm2_alg_util_flags_hash);
        if (ctx.sig_hash_algorithm == TPM2_ALG_ERROR) {
            LOG_ERR(
                    "Could not convert signature hash algorithm selection, got: \"%s\"",
                    value);
            return false;
        }
        break;
    case 0:
        ctx.sig_scheme = tpm2_alg_util_from_optarg(value,
                tpm2_alg_util_flags_sig);
        if (ctx.sig_scheme == TPM2_ALG_ERROR) {
            LOG_ERR("Unknown signing scheme, got: \"%s\"", value);
            return false;
        }
        break;
    }

    return true;
}

static bool tpm2_tool_onstart(tpm2_options **opts) {

    static const struct option topts[] = {
        { "hierarchy-auth", required_argument, NULL, 'P' },
        { "key-context",    required_argument, NULL, 'c' },
        { "auth",           required_argument, NULL, 'p' },
        { "qualification",  required_argument, NULL, 'q' },
        { "signature",      required_argument, NULL, 's' },
        { "message",        required_argument, NULL, 'm' },
        { "format",         required_argument, NULL, 'f' },
        { "hash-algorithm", required_argument, NULL, 'g' },
        { "scheme",         required_argument, NULL,  0  },
    };

    *opts = tpm2_options_new("P:c:p:q:s:m:f:g:", ARRAY_LEN(topts), topts,
            on_option, NULL, 0);

    return *opts != NULL;
}

static bool check_input_options_and_args(void) {

    if (!ctx.key.ctx_path) {
        LOG_ERR("Specify the signing key to use for signing attestation.");
        return false;
    }

    if (!ctx.signature_path) {
        LOG_ERR("Specify the file path to store the signature of the attestation data.");
        return false;
    }

    if (!ctx.message_path) {
        LOG_ERR("Specify the file path to store the attestation data.");
        return false;
    }

    return true;
}

static tool_rc process_inputs(ESYS_CONTEXT *ectx) {

    /*
     * Load auths
     */
    tool_rc rc = tpm2_util_object_load_auth(ectx,
        ctx.endorsement_hierarchy.ctx_path, ctx.endorsement_hierarchy.auth_str,
        &ctx.endorsement_hierarchy.object, false, TPM2_HANDLE_FLAGS_E);
    if (rc != tool_rc_success) {
        LOG_ERR("Invalid endorsement hierarchy authorization");
        return rc;
    }

    rc = tpm2_util_object_load_auth(ectx, ctx.key.ctx_path,
            ctx.key.auth_str, &ctx.key.object, false,
            TPM2_HANDLES_FLAGS_TRANSIENT|TPM2_HANDLES_FLAGS_PERSISTENT);
    if (rc != tool_rc_success) {
        LOG_ERR("Invalid key authorization");
        return rc;
    }

    /*
     * Setup signature scheme
     */
    rc = tpm2_alg_util_get_signature_scheme(ectx,
            ctx.key.object.tr_handle, &ctx.sig_hash_algorithm, ctx.sig_scheme,
            &ctx.in_scheme);
    if (rc != tool_rc_success) {
        return rc;
    }

    return tool_rc_success;
}

static tool_rc process_outputs(ESYS_CONTEXT *ectx) {

    UNUSED(ectx);

    bool result = true;
    if (ctx.signature_path) {
        result = tpm2_convert_sig_save(ctx.signature, ctx.sig_format,
                ctx.signature_path);
    }
    if (!result) {
        LOG_ERR("Failed to save the signature data.");
        return tool_rc_general_error;
    }

    if (ctx.message_path) {
        result = files_save_bytes_to_file(ctx.message_path,
                (UINT8*) ctx.audit_info->attestationData, ctx.audit_info->size);
    }
    if (!result) {
        LOG_ERR("Failed to save the attestation data.");
        return tool_rc_general_error;
    }

    return tool_rc_success;
}

static tool_rc tpm2_tool_onrun(ESYS_CONTEXT *ectx, tpm2_option_flags flags) {

    UNUSED(flags);

    //Check input arguments
    bool result = check_input_options_and_args();
    if (!result) {
        return tool_rc_option_error;
    }

    //Process inputs
    tool_rc rc = process_inputs(ectx);
    if (rc != tool_rc_success) {
        return rc;
    }

    //ESAPI call
    rc = tpm2_getcommandauditdigest(ectx, &ctx.endorsement_hierarchy.object,
    &ctx.key.object, &ctx.in_scheme, &ctx.qualification_data, &ctx.audit_info,
    &ctx.signature);
    if (rc != tool_rc_success) {
        return rc;
    }

    //Process Outputs
    rc = process_outputs(ectx);
    if (rc != tool_rc_success) {
        return rc;
    }

    return tool_rc_success;
}

static tool_rc tpm2_tool_onstop(ESYS_CONTEXT *ectx) {

    UNUSED(ectx);

    tool_rc rc = tpm2_session_close(&ctx.key.object.session);
    if (rc != tool_rc_success) {
        LOG_ERR("Failed closing auth session for signing key handle.");
    }

    tool_rc tmp_rc = tpm2_session_close(
        &ctx.endorsement_hierarchy.object.session);
    if (rc != tool_rc_success) {
        LOG_ERR("Failed closing auth session for endorsement hierarchy handle.");
        return tmp_rc;
    }

    return rc;
}

// Register this tool with tpm2_tool.c
TPM2_TOOL_REGISTER("getcommandauditdigest", tpm2_tool_onstart, tpm2_tool_onrun, tpm2_tool_onstop, NULL)