Return to tcg_pts_attr_aik.c CVS log | Up to [ELWIX - Embedded LightWeight unIX -] / embedaddon / strongswan / src / libimcv / tcg / pts |
1.1 misho 1: /* 2: * Copyright (C) 2011-2012 Sansar Choinyambuu 3: * Copyright (C) 2011-2014 Andreas Steffen 4: * HSR Hochschule fuer Technik Rapperswil 5: * 6: * This program is free software; you can redistribute it and/or modify it 7: * under the terms of the GNU General Public License as published by the 8: * Free Software Foundation; either version 2 of the License, or (at your 9: * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>. 10: * 11: * This program is distributed in the hope that it will be useful, but 12: * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY 13: * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 14: * for more details. 15: */ 16: 17: #include "tcg_pts_attr_aik.h" 18: 19: #include <pa_tnc/pa_tnc_msg.h> 20: #include <bio/bio_writer.h> 21: #include <bio/bio_reader.h> 22: #include <utils/debug.h> 23: 24: typedef struct private_tcg_pts_attr_aik_t private_tcg_pts_attr_aik_t; 25: 26: /** 27: * Attestation Identity Key 28: * see section 3.13 of PTS Protocol: Binding to TNC IF-M Specification 29: * 30: * 1 2 3 31: * 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 32: * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 33: * | Flags | Attestation Identity Key (Variable Length) ~ 34: * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 35: * | Attestation Identity Key (Variable Length) ~ 36: * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 37: */ 38: 39: #define PTS_AIK_SIZE 4 40: #define PTS_AIK_FLAGS_NONE 0 41: #define PTS_AIK_FLAGS_NAKED_KEY (1<<7) 42: /** 43: * Private data of an tcg_pts_attr_aik_t object. 44: */ 45: struct private_tcg_pts_attr_aik_t { 46: 47: /** 48: * Public members of tcg_pts_attr_aik_t 49: */ 50: tcg_pts_attr_aik_t public; 51: 52: /** 53: * Vendor-specific attribute type 54: */ 55: pen_type_t type; 56: 57: /** 58: * Length of attribute value 59: */ 60: size_t length; 61: 62: /** 63: * Attribute value or segment 64: */ 65: chunk_t value; 66: 67: /** 68: * Noskip flag 69: */ 70: bool noskip_flag; 71: 72: /** 73: * AIK Certificate or Public Key 74: */ 75: certificate_t *aik; 76: 77: /** 78: * Reference count 79: */ 80: refcount_t ref; 81: }; 82: 83: METHOD(pa_tnc_attr_t, get_type, pen_type_t, 84: private_tcg_pts_attr_aik_t *this) 85: { 86: return this->type; 87: } 88: 89: METHOD(pa_tnc_attr_t, get_value, chunk_t, 90: private_tcg_pts_attr_aik_t *this) 91: { 92: return this->value; 93: } 94: 95: METHOD(pa_tnc_attr_t, get_noskip_flag, bool, 96: private_tcg_pts_attr_aik_t *this) 97: { 98: return this->noskip_flag; 99: } 100: 101: METHOD(pa_tnc_attr_t, set_noskip_flag,void, 102: private_tcg_pts_attr_aik_t *this, bool noskip) 103: { 104: this->noskip_flag = noskip; 105: } 106: 107: METHOD(pa_tnc_attr_t, build, void, 108: private_tcg_pts_attr_aik_t *this) 109: { 110: bio_writer_t *writer; 111: uint8_t flags = PTS_AIK_FLAGS_NONE; 112: cred_encoding_type_t encoding_type = CERT_ASN1_DER; 113: chunk_t aik_blob; 114: 115: if (this->value.ptr) 116: { 117: return; 118: } 119: if (this->aik->get_type(this->aik) == CERT_TRUSTED_PUBKEY) 120: { 121: flags |= PTS_AIK_FLAGS_NAKED_KEY; 122: encoding_type = PUBKEY_SPKI_ASN1_DER; 123: } 124: if (!this->aik->get_encoding(this->aik, encoding_type, &aik_blob)) 125: { 126: DBG1(DBG_TNC, "encoding of Attestation Identity Key failed"); 127: aik_blob = chunk_empty; 128: } 129: writer = bio_writer_create(PTS_AIK_SIZE); 130: writer->write_uint8(writer, flags); 131: writer->write_data (writer, aik_blob); 132: this->value = writer->extract_buf(writer); 133: this->length = this->value.len; 134: writer->destroy(writer); 135: free(aik_blob.ptr); 136: } 137: 138: METHOD(pa_tnc_attr_t, process, status_t, 139: private_tcg_pts_attr_aik_t *this, uint32_t *offset) 140: { 141: bio_reader_t *reader; 142: uint8_t flags; 143: certificate_type_t type; 144: chunk_t aik_blob; 145: 146: *offset = 0; 147: 148: if (this->value.len < this->length) 149: { 150: return NEED_MORE; 151: } 152: if (this->value.len < PTS_AIK_SIZE) 153: { 154: DBG1(DBG_TNC, "insufficient data for Attestation Identity Key"); 155: return FAILED; 156: } 157: reader = bio_reader_create(this->value); 158: reader->read_uint8(reader, &flags); 159: reader->read_data (reader, reader->remaining(reader), &aik_blob); 160: 161: type = (flags & PTS_AIK_FLAGS_NAKED_KEY) ? CERT_TRUSTED_PUBKEY : CERT_X509; 162: 163: this->aik = lib->creds->create(lib->creds, CRED_CERTIFICATE, type, 164: BUILD_BLOB_PEM, aik_blob, BUILD_END); 165: reader->destroy(reader); 166: 167: if (!this->aik) 168: { 169: DBG1(DBG_TNC, "parsing of Attestation Identity Key failed"); 170: *offset = 0; 171: return FAILED; 172: } 173: return SUCCESS; 174: } 175: 176: METHOD(pa_tnc_attr_t, add_segment, void, 177: private_tcg_pts_attr_aik_t *this, chunk_t segment) 178: { 179: this->value = chunk_cat("mc", this->value, segment); 180: } 181: 182: METHOD(pa_tnc_attr_t, get_ref, pa_tnc_attr_t*, 183: private_tcg_pts_attr_aik_t *this) 184: { 185: ref_get(&this->ref); 186: return &this->public.pa_tnc_attribute; 187: } 188: 189: METHOD(pa_tnc_attr_t, destroy, void, 190: private_tcg_pts_attr_aik_t *this) 191: { 192: if (ref_put(&this->ref)) 193: { 194: DESTROY_IF(this->aik); 195: free(this->value.ptr); 196: free(this); 197: } 198: } 199: 200: METHOD(tcg_pts_attr_aik_t, get_aik, certificate_t*, 201: private_tcg_pts_attr_aik_t *this) 202: { 203: return this->aik; 204: } 205: 206: /** 207: * Described in header. 208: */ 209: pa_tnc_attr_t *tcg_pts_attr_aik_create(certificate_t *aik) 210: { 211: private_tcg_pts_attr_aik_t *this; 212: 213: INIT(this, 214: .public = { 215: .pa_tnc_attribute = { 216: .get_type = _get_type, 217: .get_value = _get_value, 218: .get_noskip_flag = _get_noskip_flag, 219: .set_noskip_flag = _set_noskip_flag, 220: .build = _build, 221: .process = _process, 222: .add_segment = _add_segment, 223: .get_ref = _get_ref, 224: .destroy = _destroy, 225: }, 226: .get_aik = _get_aik, 227: }, 228: .type = { PEN_TCG, TCG_PTS_AIK }, 229: .aik = aik->get_ref(aik), 230: .ref = 1, 231: ); 232: 233: return &this->public.pa_tnc_attribute; 234: } 235: 236: 237: /** 238: * Described in header. 239: */ 240: pa_tnc_attr_t *tcg_pts_attr_aik_create_from_data(size_t length, chunk_t data) 241: { 242: private_tcg_pts_attr_aik_t *this; 243: 244: INIT(this, 245: .public = { 246: .pa_tnc_attribute = { 247: .get_type = _get_type, 248: .get_value = _get_value, 249: .get_noskip_flag = _get_noskip_flag, 250: .set_noskip_flag = _set_noskip_flag, 251: .build = _build, 252: .process = _process, 253: .add_segment = _add_segment, 254: .get_ref = _get_ref, 255: .destroy = _destroy, 256: }, 257: .get_aik = _get_aik, 258: }, 259: .type = { PEN_TCG, TCG_PTS_AIK }, 260: .length = length, 261: .value = chunk_clone(data), 262: .ref = 1, 263: ); 264: 265: return &this->public.pa_tnc_attribute; 266: }