]>
git.saurik.com Git - apple/security.git/blob - OSX/include/security_asn1/SecAsn1Coder.c
2 * Copyright (c) 2003-2006,2008-2013 Apple Inc. All Rights Reserved.
4 * @APPLE_LICENSE_HEADER_START@
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
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.
21 * @APPLE_LICENSE_HEADER_END@
23 * SecAsn1Coder.h: ANS1 encode/decode object, ANSI C version.
26 #include "SecAsn1Coder.h"
31 #include <Security/SecBase.h>
34 * Default chunk size for new arena pool.
35 * FIXME: analyze & measure different defaults here. I'm pretty sure
36 * that only performance - not correct behavior - is affected by
37 * an arena pool's chunk size.
39 #define CHUNKSIZE_DEF 1024
42 * Caller's SecAsn1CoderRef points to one of these.
44 typedef struct SecAsn1Coder
{
49 * Create/destroy SecAsn1Coder object.
51 OSStatus
SecAsn1CoderCreate(
52 SecAsn1CoderRef
*coder
)
57 SecAsn1CoderRef _coder
= (SecAsn1CoderRef
)malloc(sizeof(SecAsn1Coder_t
));
58 _coder
->mPool
= PORT_NewArena(CHUNKSIZE_DEF
);
59 if(_coder
->mPool
== NULL
) {
61 return errSecAllocate
;
67 OSStatus
SecAsn1CoderRelease(
68 SecAsn1CoderRef coder
)
73 if(coder
->mPool
!= NULL
) {
75 * Note: we're asking for a memory zero here, but
76 * PORT_FreeArena doesn't do that (yet).
78 PORT_FreeArena(coder
->mPool
, PR_TRUE
);
86 * DER decode an untyped item per the specified template array.
87 * The result is allocated in this SecAsn1Coder's memory pool and
88 * is freed when this object is released.
90 * The dest pointer is a template-specific struct allocated by the caller
91 * and must be zeroed by the caller.
93 OSStatus
SecAsn1Decode(
94 SecAsn1CoderRef coder
,
95 const void *src
, // DER-encoded source
97 const SecAsn1Template
*templ
,
100 if((coder
== NULL
) || (src
== NULL
) || (templ
== NULL
) || (dest
== NULL
)) {
103 SECStatus prtn
= SEC_ASN1Decode(coder
->mPool
, dest
, templ
, (const char *)src
, len
);
108 return errSecSuccess
;
113 * Convenience routine, decode from a SecAsn1Item.
115 OSStatus
SecAsn1DecodeData(
116 SecAsn1CoderRef coder
,
117 const SecAsn1Item
*src
,
118 const SecAsn1Template
*templ
,
121 return SecAsn1Decode(coder
, src
->Data
, src
->Length
, templ
, dest
);
125 * DER encode. The encoded data (in dest.Data) is allocated in this
126 * SecAsn1Coder's memory pool and is freed when this object is released.
128 * The src pointer is a template-specific struct.
130 OSStatus
SecAsn1EncodeItem(
131 SecAsn1CoderRef coder
,
133 const SecAsn1Template
*templ
,
136 if((coder
== NULL
) || (src
== NULL
) || (templ
== NULL
) || (dest
== NULL
)) {
142 SecAsn1Item
*rtnItem
= SEC_ASN1EncodeItem(coder
->mPool
, dest
, src
, templ
);
143 if(rtnItem
== NULL
) {
144 /* FIXME what to return here? */
148 return errSecSuccess
;
153 * Some alloc-related methods which come in handy when using
154 * this object. All memory is allocated using this object's
155 * memory pool. Caller never has to free it. Used for
156 * temp allocs of memory which only needs a scope which is the
157 * same as this object.
159 * These return a errSecAllocate in the highly unlikely event of
163 SecAsn1CoderRef coder
,
166 #pragma clang diagnostic push
167 #pragma clang diagnostic ignored "-Wnonnull"
168 // After introducing nullability annotations, coder is supposed to be nonnull, suppress the warning
172 #pragma clang diagnostic pop
173 return PORT_ArenaAlloc(coder
->mPool
, len
);
176 /* malloc item.Data, set item.Length */
177 OSStatus
SecAsn1AllocItem(
178 SecAsn1CoderRef coder
,
182 if((coder
== NULL
) || (item
== NULL
)) {
185 item
->Data
= (uint8_t *)PORT_ArenaAlloc(coder
->mPool
, len
);
186 if(item
->Data
== NULL
) {
187 return errSecAllocate
;
190 return errSecSuccess
;
193 /* malloc and copy, various forms */
194 OSStatus
SecAsn1AllocCopy(
195 SecAsn1CoderRef coder
,
203 OSStatus ortn
= SecAsn1AllocItem(coder
, dest
, len
);
207 memmove(dest
->Data
, src
, len
);
208 return errSecSuccess
;
211 OSStatus
SecAsn1AllocCopyItem(
212 SecAsn1CoderRef coder
,
213 const SecAsn1Item
*src
,
216 return SecAsn1AllocCopy(coder
, src
->Data
, src
->Length
, dest
);
219 bool SecAsn1OidCompare(const SecAsn1Oid
*oid1
, const SecAsn1Oid
*oid2
) {
222 if (oid1
->Length
!= oid2
->Length
)
224 return !memcmp(oid1
->Data
, oid2
->Data
, oid1
->Length
);