mbed TLS library

Dependents:   HTTPClient-SSL WS_SERVER

Committer:
ansond
Date:
Thu Jun 11 03:27:03 2015 +0000
Revision:
0:137634ff4186
initial commit

Who changed what in which revision?

UserRevisionLine numberNew contents of line
ansond 0:137634ff4186 1 /**
ansond 0:137634ff4186 2 * \file asn1.h
ansond 0:137634ff4186 3 *
ansond 0:137634ff4186 4 * \brief Generic ASN.1 parsing
ansond 0:137634ff4186 5 *
ansond 0:137634ff4186 6 * Copyright (C) 2006-2013, ARM Limited, All Rights Reserved
ansond 0:137634ff4186 7 *
ansond 0:137634ff4186 8 * This file is part of mbed TLS (https://tls.mbed.org)
ansond 0:137634ff4186 9 *
ansond 0:137634ff4186 10 * This program is free software; you can redistribute it and/or modify
ansond 0:137634ff4186 11 * it under the terms of the GNU General Public License as published by
ansond 0:137634ff4186 12 * the Free Software Foundation; either version 2 of the License, or
ansond 0:137634ff4186 13 * (at your option) any later version.
ansond 0:137634ff4186 14 *
ansond 0:137634ff4186 15 * This program is distributed in the hope that it will be useful,
ansond 0:137634ff4186 16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
ansond 0:137634ff4186 17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
ansond 0:137634ff4186 18 * GNU General Public License for more details.
ansond 0:137634ff4186 19 *
ansond 0:137634ff4186 20 * You should have received a copy of the GNU General Public License along
ansond 0:137634ff4186 21 * with this program; if not, write to the Free Software Foundation, Inc.,
ansond 0:137634ff4186 22 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
ansond 0:137634ff4186 23 */
ansond 0:137634ff4186 24 #ifndef POLARSSL_ASN1_H
ansond 0:137634ff4186 25 #define POLARSSL_ASN1_H
ansond 0:137634ff4186 26
ansond 0:137634ff4186 27 #if !defined(POLARSSL_CONFIG_FILE)
ansond 0:137634ff4186 28 #include "config.h"
ansond 0:137634ff4186 29 #else
ansond 0:137634ff4186 30 #include POLARSSL_CONFIG_FILE
ansond 0:137634ff4186 31 #endif
ansond 0:137634ff4186 32
ansond 0:137634ff4186 33 #include <stddef.h>
ansond 0:137634ff4186 34
ansond 0:137634ff4186 35 #if defined(POLARSSL_BIGNUM_C)
ansond 0:137634ff4186 36 #include "bignum.h"
ansond 0:137634ff4186 37 #endif
ansond 0:137634ff4186 38
ansond 0:137634ff4186 39 /**
ansond 0:137634ff4186 40 * \addtogroup asn1_module
ansond 0:137634ff4186 41 * \{
ansond 0:137634ff4186 42 */
ansond 0:137634ff4186 43
ansond 0:137634ff4186 44 /**
ansond 0:137634ff4186 45 * \name ASN1 Error codes
ansond 0:137634ff4186 46 * These error codes are OR'ed to X509 error codes for
ansond 0:137634ff4186 47 * higher error granularity.
ansond 0:137634ff4186 48 * ASN1 is a standard to specify data structures.
ansond 0:137634ff4186 49 * \{
ansond 0:137634ff4186 50 */
ansond 0:137634ff4186 51 #define POLARSSL_ERR_ASN1_OUT_OF_DATA -0x0060 /**< Out of data when parsing an ASN1 data structure. */
ansond 0:137634ff4186 52 #define POLARSSL_ERR_ASN1_UNEXPECTED_TAG -0x0062 /**< ASN1 tag was of an unexpected value. */
ansond 0:137634ff4186 53 #define POLARSSL_ERR_ASN1_INVALID_LENGTH -0x0064 /**< Error when trying to determine the length or invalid length. */
ansond 0:137634ff4186 54 #define POLARSSL_ERR_ASN1_LENGTH_MISMATCH -0x0066 /**< Actual length differs from expected length. */
ansond 0:137634ff4186 55 #define POLARSSL_ERR_ASN1_INVALID_DATA -0x0068 /**< Data is invalid. (not used) */
ansond 0:137634ff4186 56 #define POLARSSL_ERR_ASN1_MALLOC_FAILED -0x006A /**< Memory allocation failed */
ansond 0:137634ff4186 57 #define POLARSSL_ERR_ASN1_BUF_TOO_SMALL -0x006C /**< Buffer too small when writing ASN.1 data structure. */
ansond 0:137634ff4186 58
ansond 0:137634ff4186 59 /* \} name */
ansond 0:137634ff4186 60
ansond 0:137634ff4186 61 /**
ansond 0:137634ff4186 62 * \name DER constants
ansond 0:137634ff4186 63 * These constants comply with DER encoded the ANS1 type tags.
ansond 0:137634ff4186 64 * DER encoding uses hexadecimal representation.
ansond 0:137634ff4186 65 * An example DER sequence is:\n
ansond 0:137634ff4186 66 * - 0x02 -- tag indicating INTEGER
ansond 0:137634ff4186 67 * - 0x01 -- length in octets
ansond 0:137634ff4186 68 * - 0x05 -- value
ansond 0:137634ff4186 69 * Such sequences are typically read into \c ::x509_buf.
ansond 0:137634ff4186 70 * \{
ansond 0:137634ff4186 71 */
ansond 0:137634ff4186 72 #define ASN1_BOOLEAN 0x01
ansond 0:137634ff4186 73 #define ASN1_INTEGER 0x02
ansond 0:137634ff4186 74 #define ASN1_BIT_STRING 0x03
ansond 0:137634ff4186 75 #define ASN1_OCTET_STRING 0x04
ansond 0:137634ff4186 76 #define ASN1_NULL 0x05
ansond 0:137634ff4186 77 #define ASN1_OID 0x06
ansond 0:137634ff4186 78 #define ASN1_UTF8_STRING 0x0C
ansond 0:137634ff4186 79 #define ASN1_SEQUENCE 0x10
ansond 0:137634ff4186 80 #define ASN1_SET 0x11
ansond 0:137634ff4186 81 #define ASN1_PRINTABLE_STRING 0x13
ansond 0:137634ff4186 82 #define ASN1_T61_STRING 0x14
ansond 0:137634ff4186 83 #define ASN1_IA5_STRING 0x16
ansond 0:137634ff4186 84 #define ASN1_UTC_TIME 0x17
ansond 0:137634ff4186 85 #define ASN1_GENERALIZED_TIME 0x18
ansond 0:137634ff4186 86 #define ASN1_UNIVERSAL_STRING 0x1C
ansond 0:137634ff4186 87 #define ASN1_BMP_STRING 0x1E
ansond 0:137634ff4186 88 #define ASN1_PRIMITIVE 0x00
ansond 0:137634ff4186 89 #define ASN1_CONSTRUCTED 0x20
ansond 0:137634ff4186 90 #define ASN1_CONTEXT_SPECIFIC 0x80
ansond 0:137634ff4186 91 /* \} name */
ansond 0:137634ff4186 92 /* \} addtogroup asn1_module */
ansond 0:137634ff4186 93
ansond 0:137634ff4186 94 /** Returns the size of the binary string, without the trailing \\0 */
ansond 0:137634ff4186 95 #define OID_SIZE(x) (sizeof(x) - 1)
ansond 0:137634ff4186 96
ansond 0:137634ff4186 97 /**
ansond 0:137634ff4186 98 * Compares an asn1_buf structure to a reference OID.
ansond 0:137634ff4186 99 *
ansond 0:137634ff4186 100 * Only works for 'defined' oid_str values (OID_HMAC_SHA1), you cannot use a
ansond 0:137634ff4186 101 * 'unsigned char *oid' here!
ansond 0:137634ff4186 102 *
ansond 0:137634ff4186 103 * Warning: returns true when the OIDs are equal (unlike memcmp)!
ansond 0:137634ff4186 104 */
ansond 0:137634ff4186 105 #define OID_CMP(oid_str, oid_buf) \
ansond 0:137634ff4186 106 ( ( OID_SIZE(oid_str) == (oid_buf)->len ) && \
ansond 0:137634ff4186 107 memcmp( (oid_str), (oid_buf)->p, (oid_buf)->len) == 0 )
ansond 0:137634ff4186 108
ansond 0:137634ff4186 109 #ifdef __cplusplus
ansond 0:137634ff4186 110 extern "C" {
ansond 0:137634ff4186 111 #endif
ansond 0:137634ff4186 112
ansond 0:137634ff4186 113 /**
ansond 0:137634ff4186 114 * \name Functions to parse ASN.1 data structures
ansond 0:137634ff4186 115 * \{
ansond 0:137634ff4186 116 */
ansond 0:137634ff4186 117
ansond 0:137634ff4186 118 /**
ansond 0:137634ff4186 119 * Type-length-value structure that allows for ASN1 using DER.
ansond 0:137634ff4186 120 */
ansond 0:137634ff4186 121 typedef struct _asn1_buf
ansond 0:137634ff4186 122 {
ansond 0:137634ff4186 123 int tag; /**< ASN1 type, e.g. ASN1_UTF8_STRING. */
ansond 0:137634ff4186 124 size_t len; /**< ASN1 length, e.g. in octets. */
ansond 0:137634ff4186 125 unsigned char *p; /**< ASN1 data, e.g. in ASCII. */
ansond 0:137634ff4186 126 }
ansond 0:137634ff4186 127 asn1_buf;
ansond 0:137634ff4186 128
ansond 0:137634ff4186 129 /**
ansond 0:137634ff4186 130 * Container for ASN1 bit strings.
ansond 0:137634ff4186 131 */
ansond 0:137634ff4186 132 typedef struct _asn1_bitstring
ansond 0:137634ff4186 133 {
ansond 0:137634ff4186 134 size_t len; /**< ASN1 length, e.g. in octets. */
ansond 0:137634ff4186 135 unsigned char unused_bits; /**< Number of unused bits at the end of the string */
ansond 0:137634ff4186 136 unsigned char *p; /**< Raw ASN1 data for the bit string */
ansond 0:137634ff4186 137 }
ansond 0:137634ff4186 138 asn1_bitstring;
ansond 0:137634ff4186 139
ansond 0:137634ff4186 140 /**
ansond 0:137634ff4186 141 * Container for a sequence of ASN.1 items
ansond 0:137634ff4186 142 */
ansond 0:137634ff4186 143 typedef struct _asn1_sequence
ansond 0:137634ff4186 144 {
ansond 0:137634ff4186 145 asn1_buf buf; /**< Buffer containing the given ASN.1 item. */
ansond 0:137634ff4186 146 struct _asn1_sequence *next; /**< The next entry in the sequence. */
ansond 0:137634ff4186 147 }
ansond 0:137634ff4186 148 asn1_sequence;
ansond 0:137634ff4186 149
ansond 0:137634ff4186 150 /**
ansond 0:137634ff4186 151 * Container for a sequence or list of 'named' ASN.1 data items
ansond 0:137634ff4186 152 */
ansond 0:137634ff4186 153 typedef struct _asn1_named_data
ansond 0:137634ff4186 154 {
ansond 0:137634ff4186 155 asn1_buf oid; /**< The object identifier. */
ansond 0:137634ff4186 156 asn1_buf val; /**< The named value. */
ansond 0:137634ff4186 157 struct _asn1_named_data *next; /**< The next entry in the sequence. */
ansond 0:137634ff4186 158 unsigned char next_merged; /**< Merge next item into the current one? */
ansond 0:137634ff4186 159 }
ansond 0:137634ff4186 160 asn1_named_data;
ansond 0:137634ff4186 161
ansond 0:137634ff4186 162 /**
ansond 0:137634ff4186 163 * \brief Get the length of an ASN.1 element.
ansond 0:137634ff4186 164 * Updates the pointer to immediately behind the length.
ansond 0:137634ff4186 165 *
ansond 0:137634ff4186 166 * \param p The position in the ASN.1 data
ansond 0:137634ff4186 167 * \param end End of data
ansond 0:137634ff4186 168 * \param len The variable that will receive the value
ansond 0:137634ff4186 169 *
ansond 0:137634ff4186 170 * \return 0 if successful, POLARSSL_ERR_ASN1_OUT_OF_DATA on reaching
ansond 0:137634ff4186 171 * end of data, POLARSSL_ERR_ASN1_INVALID_LENGTH if length is
ansond 0:137634ff4186 172 * unparseable.
ansond 0:137634ff4186 173 */
ansond 0:137634ff4186 174 int asn1_get_len( unsigned char **p,
ansond 0:137634ff4186 175 const unsigned char *end,
ansond 0:137634ff4186 176 size_t *len );
ansond 0:137634ff4186 177
ansond 0:137634ff4186 178 /**
ansond 0:137634ff4186 179 * \brief Get the tag and length of the tag. Check for the requested tag.
ansond 0:137634ff4186 180 * Updates the pointer to immediately behind the tag and length.
ansond 0:137634ff4186 181 *
ansond 0:137634ff4186 182 * \param p The position in the ASN.1 data
ansond 0:137634ff4186 183 * \param end End of data
ansond 0:137634ff4186 184 * \param len The variable that will receive the length
ansond 0:137634ff4186 185 * \param tag The expected tag
ansond 0:137634ff4186 186 *
ansond 0:137634ff4186 187 * \return 0 if successful, POLARSSL_ERR_ASN1_UNEXPECTED_TAG if tag did
ansond 0:137634ff4186 188 * not match requested tag, or another specific ASN.1 error code.
ansond 0:137634ff4186 189 */
ansond 0:137634ff4186 190 int asn1_get_tag( unsigned char **p,
ansond 0:137634ff4186 191 const unsigned char *end,
ansond 0:137634ff4186 192 size_t *len, int tag );
ansond 0:137634ff4186 193
ansond 0:137634ff4186 194 /**
ansond 0:137634ff4186 195 * \brief Retrieve a boolean ASN.1 tag and its value.
ansond 0:137634ff4186 196 * Updates the pointer to immediately behind the full tag.
ansond 0:137634ff4186 197 *
ansond 0:137634ff4186 198 * \param p The position in the ASN.1 data
ansond 0:137634ff4186 199 * \param end End of data
ansond 0:137634ff4186 200 * \param val The variable that will receive the value
ansond 0:137634ff4186 201 *
ansond 0:137634ff4186 202 * \return 0 if successful or a specific ASN.1 error code.
ansond 0:137634ff4186 203 */
ansond 0:137634ff4186 204 int asn1_get_bool( unsigned char **p,
ansond 0:137634ff4186 205 const unsigned char *end,
ansond 0:137634ff4186 206 int *val );
ansond 0:137634ff4186 207
ansond 0:137634ff4186 208 /**
ansond 0:137634ff4186 209 * \brief Retrieve an integer ASN.1 tag and its value.
ansond 0:137634ff4186 210 * Updates the pointer to immediately behind the full tag.
ansond 0:137634ff4186 211 *
ansond 0:137634ff4186 212 * \param p The position in the ASN.1 data
ansond 0:137634ff4186 213 * \param end End of data
ansond 0:137634ff4186 214 * \param val The variable that will receive the value
ansond 0:137634ff4186 215 *
ansond 0:137634ff4186 216 * \return 0 if successful or a specific ASN.1 error code.
ansond 0:137634ff4186 217 */
ansond 0:137634ff4186 218 int asn1_get_int( unsigned char **p,
ansond 0:137634ff4186 219 const unsigned char *end,
ansond 0:137634ff4186 220 int *val );
ansond 0:137634ff4186 221
ansond 0:137634ff4186 222 /**
ansond 0:137634ff4186 223 * \brief Retrieve a bitstring ASN.1 tag and its value.
ansond 0:137634ff4186 224 * Updates the pointer to immediately behind the full tag.
ansond 0:137634ff4186 225 *
ansond 0:137634ff4186 226 * \param p The position in the ASN.1 data
ansond 0:137634ff4186 227 * \param end End of data
ansond 0:137634ff4186 228 * \param bs The variable that will receive the value
ansond 0:137634ff4186 229 *
ansond 0:137634ff4186 230 * \return 0 if successful or a specific ASN.1 error code.
ansond 0:137634ff4186 231 */
ansond 0:137634ff4186 232 int asn1_get_bitstring( unsigned char **p, const unsigned char *end,
ansond 0:137634ff4186 233 asn1_bitstring *bs);
ansond 0:137634ff4186 234
ansond 0:137634ff4186 235 /**
ansond 0:137634ff4186 236 * \brief Retrieve a bitstring ASN.1 tag without unused bits and its
ansond 0:137634ff4186 237 * value.
ansond 0:137634ff4186 238 * Updates the pointer to the beginning of the bit/octet string.
ansond 0:137634ff4186 239 *
ansond 0:137634ff4186 240 * \param p The position in the ASN.1 data
ansond 0:137634ff4186 241 * \param end End of data
ansond 0:137634ff4186 242 * \param len Length of the actual bit/octect string in bytes
ansond 0:137634ff4186 243 *
ansond 0:137634ff4186 244 * \return 0 if successful or a specific ASN.1 error code.
ansond 0:137634ff4186 245 */
ansond 0:137634ff4186 246 int asn1_get_bitstring_null( unsigned char **p, const unsigned char *end,
ansond 0:137634ff4186 247 size_t *len );
ansond 0:137634ff4186 248
ansond 0:137634ff4186 249 /**
ansond 0:137634ff4186 250 * \brief Parses and splits an ASN.1 "SEQUENCE OF <tag>"
ansond 0:137634ff4186 251 * Updated the pointer to immediately behind the full sequence tag.
ansond 0:137634ff4186 252 *
ansond 0:137634ff4186 253 * \param p The position in the ASN.1 data
ansond 0:137634ff4186 254 * \param end End of data
ansond 0:137634ff4186 255 * \param cur First variable in the chain to fill
ansond 0:137634ff4186 256 * \param tag Type of sequence
ansond 0:137634ff4186 257 *
ansond 0:137634ff4186 258 * \return 0 if successful or a specific ASN.1 error code.
ansond 0:137634ff4186 259 */
ansond 0:137634ff4186 260 int asn1_get_sequence_of( unsigned char **p,
ansond 0:137634ff4186 261 const unsigned char *end,
ansond 0:137634ff4186 262 asn1_sequence *cur,
ansond 0:137634ff4186 263 int tag);
ansond 0:137634ff4186 264
ansond 0:137634ff4186 265 #if defined(POLARSSL_BIGNUM_C)
ansond 0:137634ff4186 266 /**
ansond 0:137634ff4186 267 * \brief Retrieve a MPI value from an integer ASN.1 tag.
ansond 0:137634ff4186 268 * Updates the pointer to immediately behind the full tag.
ansond 0:137634ff4186 269 *
ansond 0:137634ff4186 270 * \param p The position in the ASN.1 data
ansond 0:137634ff4186 271 * \param end End of data
ansond 0:137634ff4186 272 * \param X The MPI that will receive the value
ansond 0:137634ff4186 273 *
ansond 0:137634ff4186 274 * \return 0 if successful or a specific ASN.1 or MPI error code.
ansond 0:137634ff4186 275 */
ansond 0:137634ff4186 276 int asn1_get_mpi( unsigned char **p,
ansond 0:137634ff4186 277 const unsigned char *end,
ansond 0:137634ff4186 278 mpi *X );
ansond 0:137634ff4186 279 #endif /* POLARSSL_BIGNUM_C */
ansond 0:137634ff4186 280
ansond 0:137634ff4186 281 /**
ansond 0:137634ff4186 282 * \brief Retrieve an AlgorithmIdentifier ASN.1 sequence.
ansond 0:137634ff4186 283 * Updates the pointer to immediately behind the full
ansond 0:137634ff4186 284 * AlgorithmIdentifier.
ansond 0:137634ff4186 285 *
ansond 0:137634ff4186 286 * \param p The position in the ASN.1 data
ansond 0:137634ff4186 287 * \param end End of data
ansond 0:137634ff4186 288 * \param alg The buffer to receive the OID
ansond 0:137634ff4186 289 * \param params The buffer to receive the params (if any)
ansond 0:137634ff4186 290 *
ansond 0:137634ff4186 291 * \return 0 if successful or a specific ASN.1 or MPI error code.
ansond 0:137634ff4186 292 */
ansond 0:137634ff4186 293 int asn1_get_alg( unsigned char **p,
ansond 0:137634ff4186 294 const unsigned char *end,
ansond 0:137634ff4186 295 asn1_buf *alg, asn1_buf *params );
ansond 0:137634ff4186 296
ansond 0:137634ff4186 297 /**
ansond 0:137634ff4186 298 * \brief Retrieve an AlgorithmIdentifier ASN.1 sequence with NULL or no
ansond 0:137634ff4186 299 * params.
ansond 0:137634ff4186 300 * Updates the pointer to immediately behind the full
ansond 0:137634ff4186 301 * AlgorithmIdentifier.
ansond 0:137634ff4186 302 *
ansond 0:137634ff4186 303 * \param p The position in the ASN.1 data
ansond 0:137634ff4186 304 * \param end End of data
ansond 0:137634ff4186 305 * \param alg The buffer to receive the OID
ansond 0:137634ff4186 306 *
ansond 0:137634ff4186 307 * \return 0 if successful or a specific ASN.1 or MPI error code.
ansond 0:137634ff4186 308 */
ansond 0:137634ff4186 309 int asn1_get_alg_null( unsigned char **p,
ansond 0:137634ff4186 310 const unsigned char *end,
ansond 0:137634ff4186 311 asn1_buf *alg );
ansond 0:137634ff4186 312
ansond 0:137634ff4186 313 /**
ansond 0:137634ff4186 314 * \brief Find a specific named_data entry in a sequence or list based on
ansond 0:137634ff4186 315 * the OID.
ansond 0:137634ff4186 316 *
ansond 0:137634ff4186 317 * \param list The list to seek through
ansond 0:137634ff4186 318 * \param oid The OID to look for
ansond 0:137634ff4186 319 * \param len Size of the OID
ansond 0:137634ff4186 320 *
ansond 0:137634ff4186 321 * \return NULL if not found, or a pointer to the existing entry.
ansond 0:137634ff4186 322 */
ansond 0:137634ff4186 323 asn1_named_data *asn1_find_named_data( asn1_named_data *list,
ansond 0:137634ff4186 324 const char *oid, size_t len );
ansond 0:137634ff4186 325
ansond 0:137634ff4186 326 /**
ansond 0:137634ff4186 327 * \brief Free a asn1_named_data entry
ansond 0:137634ff4186 328 *
ansond 0:137634ff4186 329 * \param entry The named data entry to free
ansond 0:137634ff4186 330 */
ansond 0:137634ff4186 331 void asn1_free_named_data( asn1_named_data *entry );
ansond 0:137634ff4186 332
ansond 0:137634ff4186 333 /**
ansond 0:137634ff4186 334 * \brief Free all entries in a asn1_named_data list
ansond 0:137634ff4186 335 * Head will be set to NULL
ansond 0:137634ff4186 336 *
ansond 0:137634ff4186 337 * \param head Pointer to the head of the list of named data entries to free
ansond 0:137634ff4186 338 */
ansond 0:137634ff4186 339 void asn1_free_named_data_list( asn1_named_data **head );
ansond 0:137634ff4186 340
ansond 0:137634ff4186 341 #ifdef __cplusplus
ansond 0:137634ff4186 342 }
ansond 0:137634ff4186 343 #endif
ansond 0:137634ff4186 344
ansond 0:137634ff4186 345 #endif /* asn1.h */
ansond 0:137634ff4186 346