Annotation of embedaddon/strongswan/src/libcharon/encoding/payloads/certreq_payload.c, revision 1.1
1.1 ! misho 1: /*
! 2: * Copyright (C) 2005-2010 Martin Willi
! 3: * Copyright (C) 2010 revosec AG
! 4: * Copyright (C) 2005 Jan Hutter
! 5: * HSR Hochschule fuer Technik Rapperswil
! 6: *
! 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>.
! 11: *
! 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
! 15: * for more details.
! 16: */
! 17:
! 18: #include <stddef.h>
! 19:
! 20: #include <daemon.h>
! 21: #include <crypto/hashers/hasher.h>
! 22: #include <encoding/payloads/cert_payload.h>
! 23:
! 24: #include "certreq_payload.h"
! 25:
! 26: typedef struct private_certreq_payload_t private_certreq_payload_t;
! 27:
! 28: /**
! 29: * Private data of an certreq_payload_t object.
! 30: */
! 31: struct private_certreq_payload_t {
! 32:
! 33: /**
! 34: * Public certreq_payload_t interface.
! 35: */
! 36: certreq_payload_t public;
! 37:
! 38: /**
! 39: * Next payload type.
! 40: */
! 41: uint8_t next_payload;
! 42:
! 43: /**
! 44: * Critical flag.
! 45: */
! 46: bool critical;
! 47:
! 48: /**
! 49: * Reserved bits
! 50: */
! 51: bool reserved[7];
! 52:
! 53: /**
! 54: * Length of this payload.
! 55: */
! 56: uint16_t payload_length;
! 57:
! 58: /**
! 59: * Encoding of the CERT Data.
! 60: */
! 61: uint8_t encoding;
! 62:
! 63: /**
! 64: * The contained certreq data value.
! 65: */
! 66: chunk_t data;
! 67:
! 68: /**
! 69: * Payload type PLV2_CERTREQ or PLV1_CERTREQ
! 70: */
! 71: payload_type_t type;
! 72: };
! 73:
! 74: /**
! 75: * Encoding rules for CERTREQ payload.
! 76: */
! 77: static encoding_rule_t encodings[] = {
! 78: /* 1 Byte next payload type, stored in the field next_payload */
! 79: { U_INT_8, offsetof(private_certreq_payload_t, next_payload) },
! 80: /* the critical bit */
! 81: { FLAG, offsetof(private_certreq_payload_t, critical) },
! 82: /* 7 Bit reserved bits */
! 83: { RESERVED_BIT, offsetof(private_certreq_payload_t, reserved[0]) },
! 84: { RESERVED_BIT, offsetof(private_certreq_payload_t, reserved[1]) },
! 85: { RESERVED_BIT, offsetof(private_certreq_payload_t, reserved[2]) },
! 86: { RESERVED_BIT, offsetof(private_certreq_payload_t, reserved[3]) },
! 87: { RESERVED_BIT, offsetof(private_certreq_payload_t, reserved[4]) },
! 88: { RESERVED_BIT, offsetof(private_certreq_payload_t, reserved[5]) },
! 89: { RESERVED_BIT, offsetof(private_certreq_payload_t, reserved[6]) },
! 90: /* Length of the whole payload*/
! 91: { PAYLOAD_LENGTH, offsetof(private_certreq_payload_t, payload_length) },
! 92: /* 1 Byte CERTREQ type*/
! 93: { U_INT_8, offsetof(private_certreq_payload_t, encoding) },
! 94: /* some certreq data bytes, length is defined in PAYLOAD_LENGTH */
! 95: { CHUNK_DATA, offsetof(private_certreq_payload_t, data) }
! 96: };
! 97:
! 98: /*
! 99: 1 2 3
! 100: 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
! 101: +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
! 102: ! Next Payload !C! RESERVED ! Payload Length !
! 103: +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
! 104: ! Cert Encoding ! !
! 105: +-+-+-+-+-+-+-+-+ !
! 106: ~ Certification Authority ~
! 107: ! !
! 108: +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
! 109: */
! 110:
! 111: METHOD(payload_t, verify, status_t,
! 112: private_certreq_payload_t *this)
! 113: {
! 114: if (this->type == PLV2_CERTREQ &&
! 115: this->encoding == ENC_X509_SIGNATURE)
! 116: {
! 117: if (this->data.len % HASH_SIZE_SHA1)
! 118: {
! 119: DBG1(DBG_ENC, "invalid X509 hash length (%d) in certreq",
! 120: this->data.len);
! 121: return FAILED;
! 122: }
! 123: }
! 124: return SUCCESS;
! 125: }
! 126:
! 127: METHOD(payload_t, get_encoding_rules, int,
! 128: private_certreq_payload_t *this, encoding_rule_t **rules)
! 129: {
! 130: *rules = encodings;
! 131: return countof(encodings);
! 132: }
! 133:
! 134: METHOD(payload_t, get_header_length, int,
! 135: private_certreq_payload_t *this)
! 136: {
! 137: return 5;
! 138: }
! 139:
! 140: METHOD(payload_t, get_type, payload_type_t,
! 141: private_certreq_payload_t *this)
! 142: {
! 143: return this->type;
! 144: }
! 145:
! 146: METHOD(payload_t, get_next_type, payload_type_t,
! 147: private_certreq_payload_t *this)
! 148: {
! 149: return this->next_payload;
! 150: }
! 151:
! 152: METHOD(payload_t, set_next_type, void,
! 153: private_certreq_payload_t *this, payload_type_t type)
! 154: {
! 155: this->next_payload = type;
! 156: }
! 157:
! 158: METHOD(payload_t, get_length, size_t,
! 159: private_certreq_payload_t *this)
! 160: {
! 161: return this->payload_length;
! 162: }
! 163:
! 164: METHOD(certreq_payload_t, get_dn, identification_t*,
! 165: private_certreq_payload_t *this)
! 166: {
! 167: if (this->data.len)
! 168: {
! 169: return identification_create_from_encoding(ID_DER_ASN1_DN, this->data);
! 170: }
! 171: return NULL;
! 172: }
! 173:
! 174: METHOD(certreq_payload_t, add_keyid, void,
! 175: private_certreq_payload_t *this, chunk_t keyid)
! 176: {
! 177: this->data = chunk_cat("mc", this->data, keyid);
! 178: this->payload_length += keyid.len;
! 179: }
! 180:
! 181: typedef struct keyid_enumerator_t keyid_enumerator_t;
! 182:
! 183: /**
! 184: * enumerator to enumerate keyids
! 185: */
! 186: struct keyid_enumerator_t {
! 187: enumerator_t public;
! 188: chunk_t full;
! 189: u_char *pos;
! 190: };
! 191:
! 192: METHOD(enumerator_t, keyid_enumerate, bool,
! 193: keyid_enumerator_t *this, va_list args)
! 194: {
! 195: chunk_t *chunk;
! 196:
! 197: VA_ARGS_VGET(args, chunk);
! 198:
! 199: if (this->pos == NULL)
! 200: {
! 201: this->pos = this->full.ptr;
! 202: }
! 203: else
! 204: {
! 205: this->pos += HASH_SIZE_SHA1;
! 206: if (this->pos > (this->full.ptr + this->full.len - HASH_SIZE_SHA1))
! 207: {
! 208: this->pos = NULL;
! 209: }
! 210: }
! 211: if (this->pos)
! 212: {
! 213: chunk->ptr = this->pos;
! 214: chunk->len = HASH_SIZE_SHA1;
! 215: return TRUE;
! 216: }
! 217: return FALSE;
! 218: }
! 219:
! 220: METHOD(certreq_payload_t, create_keyid_enumerator, enumerator_t*,
! 221: private_certreq_payload_t *this)
! 222: {
! 223: keyid_enumerator_t *enumerator;
! 224:
! 225: if (this->type == PLV1_CERTREQ)
! 226: {
! 227: return enumerator_create_empty();
! 228: }
! 229: INIT(enumerator,
! 230: .public = {
! 231: .enumerate = enumerator_enumerate_default,
! 232: .venumerate = _keyid_enumerate,
! 233: .destroy = (void*)free,
! 234: },
! 235: .full = this->data,
! 236: );
! 237: return &enumerator->public;
! 238: }
! 239:
! 240: METHOD(certreq_payload_t, get_cert_type, certificate_type_t,
! 241: private_certreq_payload_t *this)
! 242: {
! 243: switch (this->encoding)
! 244: {
! 245: case ENC_X509_SIGNATURE:
! 246: return CERT_X509;
! 247: default:
! 248: return CERT_ANY;
! 249: }
! 250: }
! 251:
! 252: METHOD2(payload_t, certreq_payload_t, destroy, void,
! 253: private_certreq_payload_t *this)
! 254: {
! 255: chunk_free(&this->data);
! 256: free(this);
! 257: }
! 258:
! 259: /*
! 260: * Described in header
! 261: */
! 262: certreq_payload_t *certreq_payload_create(payload_type_t type)
! 263: {
! 264: private_certreq_payload_t *this;
! 265:
! 266: INIT(this,
! 267: .public = {
! 268: .payload_interface = {
! 269: .verify = _verify,
! 270: .get_encoding_rules = _get_encoding_rules,
! 271: .get_header_length = _get_header_length,
! 272: .get_length = _get_length,
! 273: .get_next_type = _get_next_type,
! 274: .set_next_type = _set_next_type,
! 275: .get_type = _get_type,
! 276: .destroy = _destroy,
! 277: },
! 278: .create_keyid_enumerator = _create_keyid_enumerator,
! 279: .get_cert_type = _get_cert_type,
! 280: .add_keyid = _add_keyid,
! 281: .destroy = _destroy,
! 282: .get_dn = _get_dn,
! 283: },
! 284: .next_payload = PL_NONE,
! 285: .payload_length = get_header_length(this),
! 286: .type = type,
! 287: );
! 288: return &this->public;
! 289: }
! 290:
! 291: /*
! 292: * Described in header
! 293: */
! 294: certreq_payload_t *certreq_payload_create_type(certificate_type_t type)
! 295: {
! 296: private_certreq_payload_t *this;
! 297:
! 298: this = (private_certreq_payload_t*)
! 299: certreq_payload_create(PLV2_CERTREQ);
! 300: switch (type)
! 301: {
! 302: case CERT_X509:
! 303: this->encoding = ENC_X509_SIGNATURE;
! 304: break;
! 305: default:
! 306: DBG1(DBG_ENC, "certificate type %N not supported in requests",
! 307: certificate_type_names, type);
! 308: free(this);
! 309: return NULL;
! 310: }
! 311: return &this->public;
! 312: }
! 313:
! 314: /*
! 315: * Described in header
! 316: */
! 317: certreq_payload_t *certreq_payload_create_dn(identification_t *id)
! 318: {
! 319: private_certreq_payload_t *this;
! 320:
! 321: this = (private_certreq_payload_t*)
! 322: certreq_payload_create(PLV1_CERTREQ);
! 323:
! 324: this->encoding = ENC_X509_SIGNATURE;
! 325: this->data = chunk_clone(id->get_encoding(id));
! 326: this->payload_length = get_header_length(this) + this->data.len;
! 327:
! 328: return &this->public;
! 329: }
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>