1/* 2 * Copyright (c) 2005-2011 Apple Inc. All Rights Reserved. 3 * 4 * @APPLE_LICENSE_HEADER_START@ 5 * 6 * This file contains Original Code and/or Modifications of Original Code 7 * as defined in and that are subject to the Apple Public Source License 8 * Version 2.0 (the 'License'). You may not use this file except in 9 * compliance with the License. Please obtain a copy of the License at 10 * http://www.opensource.apple.com/apsl/ and read it before using this 11 * file. 12 * 13 * The Original Code and all software distributed under the License are 14 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER 15 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, 16 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, 17 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. 18 * Please see the License for the specific language governing rights and 19 * limitations under the License. 20 * 21 * @APPLE_LICENSE_HEADER_END@ 22 */ 23 24/* 25 * DER_Decode.h - DER decoding routines 26 */ 27 28#ifndef _DER_DECODE_H_ 29#define _DER_DECODE_H_ 30 31#ifdef __cplusplus 32extern "C" { 33#endif 34 35#include <libDER/libDER.h> 36#include <stdbool.h> 37 38/* 39 * Decoding one item consists of extracting its tag, a pointer 40 * to the actual content, and the length of the content. Those 41 * three are represented by a DERDecodedInfo. 42 */ 43typedef struct { 44 DERTag tag; 45 DERItem content; 46} DERDecodedInfo; 47 48/* 49 * Basic decoding primitive. Only works with: 50 * 51 * -- definite length encoding 52 * -- one-byte tags 53 * -- max content length fits in a DERSize 54 * 55 * No malloc or copy of the contents is performed; the returned 56 * content->content.data is a pointer into the incoming der data. 57 */ 58DERReturn DERDecodeItem( 59 const DERItem *der, /* data to decode */ 60 DERDecodedInfo *decoded); /* RETURNED */ 61 62/* 63 * Given a BIT_STRING, in the form of its raw content bytes, 64 * obtain the number of unused bits and the raw bit string bytes. 65 */ 66DERReturn DERParseBitString( 67 const DERItem *contents, 68 DERItem *bitStringBytes, /* RETURNED */ 69 DERByte *numUnusedBits); /* RETURNED */ 70 71/* 72 * Given a BOOLEAN, in the form of its raw content bytes, 73 * obtain it's value. 74 */ 75DERReturn DERParseBoolean( 76 const DERItem *contents, 77 bool defaultValue, 78 bool *value); /* RETURNED */ 79 80DERReturn DERParseInteger( 81 const DERItem *contents, 82 uint32_t *value); /* RETURNED */ 83 84/* 85 * Sequence/set decode support. 86 */ 87 88/* state representing a sequence or set being decoded */ 89typedef struct { 90 DERByte *nextItem; 91 DERByte *end; 92} DERSequence; 93 94/* 95 * To decode a set or sequence, call DERDecodeSeqInit or 96 * DERDecodeSeqContentInit once, then call DERDecodeSeqNext to 97 * get each enclosed item. 98 * 99 * DERDecodeSeqNext returns DR_EndOfSequence when no more 100 * items are available. 101 */ 102 103/* 104 * Use this to parse the top level sequence's tag and content length. 105 */ 106DERReturn DERDecodeSeqInit( 107 const DERItem *der, /* data to decode */ 108 DERTag *tag, /* RETURNED tag of sequence/set. This will be 109 * either ASN1_CONSTR_SEQUENCE or 110 * ASN1_CONSTR_SET. */ 111 DERSequence *derSeq); /* RETURNED, to use in DERDecodeSeqNext */ 112 113/* 114 * Use this to start in on decoding a sequence's content, when 115 * the top-level tag and content have already been decoded. 116 */ 117DERReturn DERDecodeSeqContentInit( 118 const DERItem *content, 119 DERSequence *derSeq); /* RETURNED, to use in DERDecodeSeqNext */ 120 121/* obtain the next decoded item in a sequence or set */ 122DERReturn DERDecodeSeqNext( 123 DERSequence *derSeq, 124 DERDecodedInfo *decoded); /* RETURNED */ 125 126/* 127 * High level sequence decode. 128 */ 129 130/* 131 * Per-item decode options. 132 */ 133 134/* Explicit default, no options */ 135#define DER_DEC_NO_OPTS 0x0000 136 137/* This item optional, can be skipped during decode */ 138#define DER_DEC_OPTIONAL 0x0001 139 140/* Skip the tag check; accept anything. */ 141#define DER_DEC_ASN_ANY 0x0002 142 143/* Skip item, no write to DERDecodedInfo (but tag check still performed) */ 144#define DER_DEC_SKIP 0x0004 145 146/* Save full DER encoding in DERDecodedInfo, including tag and length. Normally 147 * only the content is saved. */ 148#define DER_DEC_SAVE_DER 0x0008 149 150/* 151 * High level sequence parse, starting with top-level tag and content. 152 * Top level tag must be ASN1_CONSTR_SEQUENCE - if it's not, and that's 153 * OK, use DERParseSequenceContent(). 154 * 155 * These never return DR_EndOfSequence - if an *unexpected* end of sequence 156 * occurs, return DR_IncompleteSeq. 157 * 158 * Results of the decoding of one item are placed in a DERItem whose address 159 * is the dest arg plus the offset value in the associated DERItemSpec. 160 * 161 * Items which are optional (DER_DEC_OPTIONAL) and which are not found, 162 * leave their associated DERDecodedInfos unmodified. 163 * 164 * Processing of a sequence ends on detection of any error or after the 165 * last DERItemSpec is processed. 166 * 167 * The sizeToZero argument, if nonzero, indicates the number of bytes 168 * starting at dest to zero before processing the sequence. This is 169 * generally desirable, particularly if there are any DER_DEC_OPTIONAL 170 * items in the sequence; skipped optional items are detected by the 171 * caller via a NULL DERDecodedInfo.content.data; if this hasn't been 172 * explicitly zeroed (generally, by passing a nonzero value of sizeToZero), 173 * skipped items can't be detected. 174 */ 175DERReturn DERParseSequence( 176 const DERItem *der, 177 DERShort numItems, /* size of itemSpecs[] */ 178 const DERItemSpec *itemSpecs, 179 void *dest, /* DERDecodedInfo(s) here RETURNED */ 180 DERSize sizeToZero); /* optional */ 181 182/* high level sequence parse, starting with sequence's content */ 183DERReturn DERParseSequenceContent( 184 const DERItem *content, 185 DERShort numItems, /* size of itemSpecs[] */ 186 const DERItemSpec *itemSpecs, 187 void *dest, /* DERDecodedInfo(s) here RETURNED */ 188 DERSize sizeToZero); /* optional */ 189 190#ifdef __cplusplus 191} 192#endif 193 194#endif /* _DER_DECODE_H_ */ 195 196