2 * Copyright (C) 2011-2012 Sansar Choinyambuu
3 * Copyright (C) 2011-2014 Andreas Steffen
5 * Copyright (C) secunet Security Networks AG
7 * This program is free software; you can redistribute it and/or modify it
8 * under the terms of the GNU General Public License as published by the
9 * Free Software Foundation; either version 2 of the License, or (at your
10 * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
12 * This program is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
14 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
18 #include "tcg_pts_attr_aik.h"
20 #include <pa_tnc/pa_tnc_msg.h>
21 #include <bio/bio_writer.h>
22 #include <bio/bio_reader.h>
23 #include <utils/debug.h>
25 typedef struct private_tcg_pts_attr_aik_t private_tcg_pts_attr_aik_t
;
28 * Attestation Identity Key
29 * see section 3.13 of PTS Protocol: Binding to TNC IF-M Specification
32 * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
33 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
34 * | Flags | Attestation Identity Key (Variable Length) ~
35 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
36 * | Attestation Identity Key (Variable Length) ~
37 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
40 #define PTS_AIK_SIZE 4
41 #define PTS_AIK_FLAGS_NONE 0
42 #define PTS_AIK_FLAGS_NAKED_KEY (1<<7)
44 * Private data of an tcg_pts_attr_aik_t object.
46 struct private_tcg_pts_attr_aik_t
{
49 * Public members of tcg_pts_attr_aik_t
51 tcg_pts_attr_aik_t
public;
54 * Vendor-specific attribute type
59 * Length of attribute value
64 * Attribute value or segment
74 * AIK Certificate or Public Key
84 METHOD(pa_tnc_attr_t
, get_type
, pen_type_t
,
85 private_tcg_pts_attr_aik_t
*this)
90 METHOD(pa_tnc_attr_t
, get_value
, chunk_t
,
91 private_tcg_pts_attr_aik_t
*this)
96 METHOD(pa_tnc_attr_t
, get_noskip_flag
, bool,
97 private_tcg_pts_attr_aik_t
*this)
99 return this->noskip_flag
;
102 METHOD(pa_tnc_attr_t
, set_noskip_flag
,void,
103 private_tcg_pts_attr_aik_t
*this, bool noskip
)
105 this->noskip_flag
= noskip
;
108 METHOD(pa_tnc_attr_t
, build
, void,
109 private_tcg_pts_attr_aik_t
*this)
111 bio_writer_t
*writer
;
112 uint8_t flags
= PTS_AIK_FLAGS_NONE
;
113 cred_encoding_type_t encoding_type
= CERT_ASN1_DER
;
120 if (this->aik
->get_type(this->aik
) == CERT_TRUSTED_PUBKEY
)
122 flags
|= PTS_AIK_FLAGS_NAKED_KEY
;
123 encoding_type
= PUBKEY_SPKI_ASN1_DER
;
125 if (!this->aik
->get_encoding(this->aik
, encoding_type
, &aik_blob
))
127 DBG1(DBG_TNC
, "encoding of Attestation Identity Key failed");
128 aik_blob
= chunk_empty
;
130 writer
= bio_writer_create(PTS_AIK_SIZE
);
131 writer
->write_uint8(writer
, flags
);
132 writer
->write_data (writer
, aik_blob
);
133 this->value
= writer
->extract_buf(writer
);
134 this->length
= this->value
.len
;
135 writer
->destroy(writer
);
139 METHOD(pa_tnc_attr_t
, process
, status_t
,
140 private_tcg_pts_attr_aik_t
*this, uint32_t *offset
)
142 bio_reader_t
*reader
;
144 certificate_type_t type
;
149 if (this->value
.len
< this->length
)
153 if (this->value
.len
< PTS_AIK_SIZE
)
155 DBG1(DBG_TNC
, "insufficient data for Attestation Identity Key");
158 reader
= bio_reader_create(this->value
);
159 reader
->read_uint8(reader
, &flags
);
160 reader
->read_data (reader
, reader
->remaining(reader
), &aik_blob
);
162 type
= (flags
& PTS_AIK_FLAGS_NAKED_KEY
) ? CERT_TRUSTED_PUBKEY
: CERT_X509
;
164 this->aik
= lib
->creds
->create(lib
->creds
, CRED_CERTIFICATE
, type
,
165 BUILD_BLOB_PEM
, aik_blob
, BUILD_END
);
166 reader
->destroy(reader
);
170 DBG1(DBG_TNC
, "parsing of Attestation Identity Key failed");
177 METHOD(pa_tnc_attr_t
, add_segment
, void,
178 private_tcg_pts_attr_aik_t
*this, chunk_t segment
)
180 this->value
= chunk_cat("mc", this->value
, segment
);
183 METHOD(pa_tnc_attr_t
, get_ref
, pa_tnc_attr_t
*,
184 private_tcg_pts_attr_aik_t
*this)
187 return &this->public.pa_tnc_attribute
;
190 METHOD(pa_tnc_attr_t
, destroy
, void,
191 private_tcg_pts_attr_aik_t
*this)
193 if (ref_put(&this->ref
))
195 DESTROY_IF(this->aik
);
196 free(this->value
.ptr
);
201 METHOD(tcg_pts_attr_aik_t
, get_aik
, certificate_t
*,
202 private_tcg_pts_attr_aik_t
*this)
208 * Described in header.
210 pa_tnc_attr_t
*tcg_pts_attr_aik_create(certificate_t
*aik
)
212 private_tcg_pts_attr_aik_t
*this;
216 .pa_tnc_attribute
= {
217 .get_type
= _get_type
,
218 .get_value
= _get_value
,
219 .get_noskip_flag
= _get_noskip_flag
,
220 .set_noskip_flag
= _set_noskip_flag
,
223 .add_segment
= _add_segment
,
229 .type
= { PEN_TCG
, TCG_PTS_AIK
},
230 .aik
= aik
->get_ref(aik
),
234 return &this->public.pa_tnc_attribute
;
239 * Described in header.
241 pa_tnc_attr_t
*tcg_pts_attr_aik_create_from_data(size_t length
, chunk_t data
)
243 private_tcg_pts_attr_aik_t
*this;
247 .pa_tnc_attribute
= {
248 .get_type
= _get_type
,
249 .get_value
= _get_value
,
250 .get_noskip_flag
= _get_noskip_flag
,
251 .set_noskip_flag
= _set_noskip_flag
,
254 .add_segment
= _add_segment
,
260 .type
= { PEN_TCG
, TCG_PTS_AIK
},
262 .value
= chunk_clone(data
),
266 return &this->public.pa_tnc_attribute
;