1/* 2 * ccder.h 3 * corecrypto 4 * 5 * Created by Michael Brouwer on 2/28/12. 6 * Copyright 2012 Apple Inc. All rights reserved. 7 * 8 */ 9 10#ifndef _CORECRYPTO_CCDER_H_ 11#define _CORECRYPTO_CCDER_H_ 12 13#include <corecrypto/ccasn1.h> 14#include <corecrypto/ccn.h> 15 16#define CCDER_MULTIBYTE_TAGS 1 17 18#ifdef CCDER_MULTIBYTE_TAGS 19typedef unsigned long ccder_tag; 20#else 21typedef uint8_t ccder_tag; 22#endif 23 24/* DER types to be used with ccder_decode and ccder_encode functions. */ 25enum { 26 CCDER_EOL = CCASN1_EOL, 27 CCDER_BOOLEAN = CCASN1_BOOLEAN, 28 CCDER_INTEGER = CCASN1_INTEGER, 29 CCDER_BIT_STRING = CCASN1_BIT_STRING, 30 CCDER_OCTET_STRING = CCASN1_OCTET_STRING, 31 CCDER_NULL = CCASN1_NULL, 32 CCDER_OBJECT_IDENTIFIER = CCASN1_OBJECT_IDENTIFIER, 33 CCDER_OBJECT_DESCRIPTOR = CCASN1_OBJECT_DESCRIPTOR, 34 /* External or instance-of 0x08 */ 35 CCDER_REAL = CCASN1_REAL, 36 CCDER_ENUMERATED = CCASN1_ENUMERATED, 37 CCDER_EMBEDDED_PDV = CCASN1_EMBEDDED_PDV, 38 CCDER_UTF8_STRING = CCASN1_UTF8_STRING, 39 /* 0x0d */ 40 /* 0x0e */ 41 /* 0x0f */ 42 CCDER_SEQUENCE = CCASN1_SEQUENCE, 43 CCDER_SET = CCASN1_SET, 44 CCDER_NUMERIC_STRING = CCASN1_NUMERIC_STRING, 45 CCDER_PRINTABLE_STRING = CCASN1_PRINTABLE_STRING, 46 CCDER_T61_STRING = CCASN1_T61_STRING, 47 CCDER_VIDEOTEX_STRING = CCASN1_VIDEOTEX_STRING, 48 CCDER_IA5_STRING = CCASN1_IA5_STRING, 49 CCDER_UTC_TIME = CCASN1_UTC_TIME, 50 CCDER_GENERALIZED_TIME = CCASN1_GENERALIZED_TIME, 51 CCDER_GRAPHIC_STRING = CCASN1_GRAPHIC_STRING, 52 CCDER_VISIBLE_STRING = CCASN1_VISIBLE_STRING, 53 CCDER_GENERAL_STRING = CCASN1_GENERAL_STRING, 54 CCDER_UNIVERSAL_STRING = CCASN1_UNIVERSAL_STRING, 55 /* 0x1d */ 56 CCDER_BMP_STRING = CCASN1_BMP_STRING, 57 CCDER_HIGH_TAG_NUMBER = CCASN1_HIGH_TAG_NUMBER, 58 CCDER_TELETEX_STRING = CCDER_T61_STRING, 59 60#ifdef CCDER_MULTIBYTE_TAGS 61 CCDER_TAG_MASK = ((ccder_tag)~0), 62 CCDER_TAGNUM_MASK = ((ccder_tag)~((ccder_tag)7 << (sizeof(ccder_tag) * 8 - 3))), 63 64 CCDER_METHOD_MASK = ((ccder_tag)1 << (sizeof(ccder_tag) * 8 - 3)), 65 CCDER_PRIMITIVE = ((ccder_tag)0 << (sizeof(ccder_tag) * 8 - 3)), 66 CCDER_CONSTRUCTED = ((ccder_tag)1 << (sizeof(ccder_tag) * 8 - 3)), 67 68 CCDER_CLASS_MASK = ((ccder_tag)3 << (sizeof(ccder_tag) * 8 - 2)), 69 CCDER_UNIVERSAL = ((ccder_tag)0 << (sizeof(ccder_tag) * 8 - 2)), 70 CCDER_APPLICATION = ((ccder_tag)1 << (sizeof(ccder_tag) * 8 - 2)), 71 CCDER_CONTEXT_SPECIFIC = ((ccder_tag)2 << (sizeof(ccder_tag) * 8 - 2)), 72 CCDER_PRIVATE = ((ccder_tag)3 << (sizeof(ccder_tag) * 8 - 2)), 73#else 74 CCDER_TAG_MASK = CCASN1_TAG_MASK, 75 CCDER_TAGNUM_MASK = CCASN1_TAGNUM_MASK, 76 77 CCDER_METHOD_MASK = CCASN1_METHOD_MASK, 78 CCDER_PRIMITIVE = CCASN1_PRIMITIVE, 79 CCDER_CONSTRUCTED = CCASN1_CONSTRUCTED, 80 81 CCDER_CLASS_MASK = CCASN1_CLASS_MASK, 82 CCDER_UNIVERSAL = CCASN1_UNIVERSAL, 83 CCDER_APPLICATION = CCASN1_APPLICATION, 84 CCDER_CONTEXT_SPECIFIC = CCASN1_CONTEXT_SPECIFIC, 85 CCDER_PRIVATE = CCASN1_PRIVATE, 86#endif 87 CCDER_CONSTRUCTED_SET = CCDER_SET | CCDER_CONSTRUCTED, 88 CCDER_CONSTRUCTED_SEQUENCE = CCDER_SEQUENCE | CCDER_CONSTRUCTED, 89}; 90 91 92#pragma mark ccder_sizeof_ functions 93 94inline CC_CONST 95size_t ccder_sizeof_tag(ccder_tag tag); 96 97inline CC_CONST 98size_t ccder_sizeof_len(size_t len); 99 100/* Returns the size of an asn1 encoded item of length l in bytes, 101 assuming a 1 byte tag. */ 102inline CC_CONST 103size_t ccder_sizeof(ccder_tag tag, size_t len); 104 105inline CC_CONST 106size_t ccder_sizeof_oid(ccoid_t oid); 107 108#pragma mark ccder_encode_ functions. 109 110/* Encode a tag backwards, der_end should point to one byte past the end of 111 destination for the tag, returns a pointer to the first byte of the tag. 112 Returns NULL if there is an encoding error. */ 113inline CC_NONNULL2 114uint8_t *ccder_encode_tag(ccder_tag tag, const uint8_t *der, uint8_t *der_end); 115 116/* Returns a pointer to the start of the len field. returns NULL if there 117 is an encoding error. */ 118inline CC_NONNULL2 119uint8_t * 120ccder_encode_len(size_t len, const uint8_t *der, uint8_t *der_end); 121 122/* der_end should point to the first byte of the content of this der item. */ 123inline CC_NONNULL3 124uint8_t * 125ccder_encode_tl(ccder_tag tag, size_t len, const uint8_t *der, uint8_t *der_end); 126 127inline CC_PURE CC_NONNULL2 128uint8_t * 129ccder_encode_body_nocopy(size_t size, const uint8_t *der, uint8_t *der_end); 130 131/* Encode the tag and length of a constructed object. der is the lower 132 bound, der_end is one byte paste where we want to write the length and 133 body_end is one byte past the end of the body of the der object we are 134 encoding the tag and length of. */ 135inline CC_NONNULL((2,3)) 136uint8_t * 137ccder_encode_constructed_tl(ccder_tag tag, const uint8_t *body_end, 138 const uint8_t *der, uint8_t *der_end); 139 140/* Encodes oid into der and returns 141 der + ccder_sizeof_oid(oid). */ 142inline CC_NONNULL1 CC_NONNULL2 143uint8_t *ccder_encode_oid(ccoid_t oid, const uint8_t *der, uint8_t *der_end); 144 145inline CC_NONNULL((3,4)) 146uint8_t *ccder_encode_implicit_integer(ccder_tag implicit_tag, 147 cc_size n, const cc_unit *s, 148 const uint8_t *der, uint8_t *der_end); 149 150inline CC_NONNULL((2,3)) 151uint8_t *ccder_encode_integer(cc_size n, const cc_unit *s, 152 const uint8_t *der, uint8_t *der_end); 153 154inline CC_NONNULL3 155uint8_t *ccder_encode_implicit_uint64(ccder_tag implicit_tag, 156 uint64_t value, 157 const uint8_t *der, uint8_t *der_end); 158 159inline CC_NONNULL3 160uint8_t *ccder_encode_uint64(uint64_t value, 161 const uint8_t *der, uint8_t *der_end); 162 163inline CC_NONNULL((3,4)) 164uint8_t *ccder_encode_implicit_octet_string(ccder_tag implicit_tag, 165 cc_size n, const cc_unit *s, 166 const uint8_t *der, 167 uint8_t *der_end); 168 169inline CC_NONNULL((2,3)) 170uint8_t *ccder_encode_octet_string(cc_size n, const cc_unit *s, 171 const uint8_t *der, uint8_t *der_end); 172 173inline CC_NONNULL((3,4)) 174uint8_t *ccder_encode_implicit_raw_octet_string(ccder_tag implicit_tag, 175 size_t s_size, const uint8_t *s, 176 const uint8_t *der, 177 uint8_t *der_end); 178 179inline CC_NONNULL((2,3)) 180uint8_t *ccder_encode_raw_octet_string(size_t s_size, const uint8_t *s, 181 const uint8_t *der, uint8_t *der_end); 182 183/* ccder_encode_body COPIES the body into the der. 184 It's inefficient – especially when you already have to convert to get to 185 the form for the body. 186 see encode integer for the right way to unify conversion and insertion */ 187inline CC_NONNULL3 188uint8_t * 189ccder_encode_body(size_t size, const uint8_t* body, 190 const uint8_t *der, uint8_t *der_end); 191 192#pragma mark ccder_decode_ functions. 193 194/* Returns a pointer to the start of the length field, and returns the decoded tag in tag. 195 returns NULL if there is a decoding error. */ 196inline CC_NONNULL((1,3)) 197const uint8_t *ccder_decode_tag(ccder_tag *tagp, const uint8_t *der, const uint8_t *der_end); 198 199inline CC_NONNULL((1,3)) 200const uint8_t *ccder_decode_len(size_t *lenp, const uint8_t *der, const uint8_t *der_end); 201 202/* Returns a pointer to the start of the der object, and returns the length in len. 203 returns NULL if there is a decoding error. */ 204inline CC_NONNULL((2,4)) 205const uint8_t *ccder_decode_tl(ccder_tag expected_tag, size_t *lenp, 206 const uint8_t *der, const uint8_t *der_end); 207 208inline CC_NONNULL((2,3)) 209const uint8_t * 210ccder_decode_constructed_tl(ccder_tag expected_tag, const uint8_t **body_end, 211 const uint8_t *der, const uint8_t *der_end); 212 213inline CC_NONNULL((1,3)) 214const uint8_t * 215ccder_decode_sequence_tl(const uint8_t **body_end, 216 const uint8_t *der, const uint8_t *der_end); 217 218inline CC_NONNULL((2,4)) 219const uint8_t *ccder_decode_uint(cc_size n, cc_unit *r, 220 const uint8_t *der, const uint8_t *der_end); 221 222inline CC_NONNULL((1,3)) 223const uint8_t *ccder_decode_uint64(uint64_t* r, 224 const uint8_t *der, const uint8_t *der_end); 225 226/* Decode SEQUENCE { r, s -- (unsigned)integer } in der into r and s. 227 Returns NULL on decode errors, returns pointer just past the end of the 228 sequence of integers otherwise. */ 229inline CC_NONNULL((2,3,5)) 230const uint8_t *ccder_decode_seqii(cc_size n, cc_unit *r, cc_unit *s, 231 const uint8_t *der, const uint8_t *der_end); 232inline CC_NONNULL_ALL 233const uint8_t *ccder_decode_oid(ccoid_t *oidp, 234 const uint8_t *der, const uint8_t *der_end); 235 236#ifndef CCDER_MULTIBYTE_TAGS 237#include <corecrypto/ccder_decode_constructed_tl.h> 238#include <corecrypto/ccder_decode_len.h> 239#include <corecrypto/ccder_decode_oid.h> 240#include <corecrypto/ccder_decode_seqii.h> 241#include <corecrypto/ccder_decode_sequence_tl.h> 242#include <corecrypto/ccder_decode_tag.h> 243#include <corecrypto/ccder_decode_tl.h> 244#include <corecrypto/ccder_decode_uint.h> 245#include <corecrypto/ccder_encode_body_nocopy.h> 246#include <corecrypto/ccder_encode_constructed_tl.h> 247#include <corecrypto/ccder_encode_implicit_integer.h> 248#include <corecrypto/ccder_encode_implicit_octet_string.h> 249#include <corecrypto/ccder_encode_implicit_uint64.h> 250#include <corecrypto/ccder_encode_integer.h> 251#include <corecrypto/ccder_encode_len.h> 252#include <corecrypto/ccder_encode_octet_string.h> 253#include <corecrypto/ccder_encode_oid.h> 254#include <corecrypto/ccder_encode_tag.h> 255#include <corecrypto/ccder_encode_tl.h> 256#include <corecrypto/ccder_encode_uint64.h> 257#include <corecrypto/ccder_sizeof.h> 258#include <corecrypto/ccder_sizeof_len.h> 259#include <corecrypto/ccder_sizeof_oid.h> 260#include <corecrypto/ccder_sizeof_tag.h> 261#endif 262 263#endif /* _CORECRYPTO_CCDER_H_ */ 264