1/*
2 * Copyright (c) 2003-2006,2008,2010-2012 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 * SecNssCoder.h: simple C++ wrapper for PLArenaPool and the
24 * high-level ANS1 encode/decode routines.
25 */
26#ifndef	_SEC_NSS_CODER_H_
27#define _SEC_NSS_CODER_H_
28
29#include <security_asn1/plarenas.h>
30#include <security_asn1/prerror.h>
31#include <Security/secasn1t.h>
32#include <security_asn1/seccomon.h>
33#include <security_utilities/alloc.h>
34#include <security_cdsa_utilities/cssmdata.h>
35
36/*
37 * Default chunk size for new arena pool.
38 * FIXME: analyze & measure different defaults here. I'm pretty sure
39 * that only performance - not correct behavior - is affected by
40 * an arena pool's chunk size.
41 */
42#define SNC_CHUNKSIZE_DEF		1024
43
44class SecNssCoder
45{
46public:
47	SecNssCoder(
48		PRUint32 chunkSize = SNC_CHUNKSIZE_DEF);
49	~SecNssCoder();
50
51	/*
52	 * BER decode an untyped item per the specified
53	 * template array. The result is allocated
54	 * by this object's PLArenaPool and is freed when
55	 * this object is deleted.
56	 *
57	 * The dest pointer is a template-specific struct allocated
58	 * by the caller and must be zeroed by the caller.
59	 *
60	 * This does not throw any exceptions; error status
61	 * (obtained from PR_GetError() is returned.
62	 */
63	PRErrorCode	decode(
64		const void				*src,		// BER-encoded source
65		size_t				len,
66		const SecAsn1Template 	*templ,
67		void					*dest);
68
69	/* convenience routine, decode from an SECItem */
70	PRErrorCode	decodeItem(
71		const SECItem			&item,		// BER-encoded source
72		const SecAsn1Template 	*templ,
73		void					*dest)
74		{
75			return decode(item.Data, item.Length, templ, dest);
76		}
77
78
79	/*
80	 * BER-encode. This object's arena pool retains a copy of
81	 * the encoded data.
82	 *
83	 * The src pointer is a template-specific struct.
84	 *
85	 * This does not throw any exceptions; error status
86	 * (obtained from PR_GetError() is returned.
87	 */
88	PRErrorCode encodeItem(
89		const void				*src,
90		const SecAsn1Template 	*templ,
91		SECItem					&dest);
92
93	/*
94	 * Some alloc-related methods which come in handy when using
95	 * this class. All memory is allocated using this object's
96	 * arena pool. Caller never has to free it. Used for
97	 * temp allocs of memory which only needs a scope which is the
98	 * same as this object.
99	 *
100	 * These throw a CssmError in the highly unlikely event of
101	 * a malloc failure.
102	 */
103	void *malloc(
104		size_t					len);
105
106	/* allocate space for num copies of specified type */
107	template <class T> T *mallocn(unsigned num = 1)
108		{ return reinterpret_cast<T *>(malloc(sizeof(T) * num)); }
109
110	/* malloc item.Data, set item.Length */
111	void allocItem(
112		SECItem					&item,
113		size_t					len);
114
115	/* malloc and copy, various forms */
116	void allocCopyItem(
117		const void				*src,
118		size_t					len,
119		SECItem					&dest);
120
121	void allocCopyItem(
122		const SECItem			&src,
123		SECItem					&dest)
124			{ allocCopyItem(src.Data, src.Length, dest); }
125
126	void allocCopyItem(
127		const CssmData			&src,
128		SECItem					&dest)
129			{ allocCopyItem(src.data(), src.length(), dest); }
130
131	PLArenaPool	*pool() const { return mPool;}
132
133private:
134	PLArenaPool		*mPool;
135};
136
137/*
138 * Stateless function to BER-encode directly into a Allocator's
139 * space. The only persistent allocated memory is allocated by
140 * the Allocator.
141 *
142 * The src pointer is a template-specific struct.
143 *
144 * This does not throw any exceptions; error status
145 * (obtained from PR_GetError() is returned.
146 */
147PRErrorCode SecNssEncodeItem(
148	const void				*src,
149	const SecAsn1Template 	*templ,
150	Allocator			&alloc,
151	SECItem					&dest);
152
153/*
154 * Same thing, using a CssmOwnedData.
155 */
156PRErrorCode SecNssEncodeItemOdata(
157	const void				*src,
158	const SecAsn1Template 	*templ,
159	CssmOwnedData			&odata);
160
161#endif	/* _SEC_NSS_CODER_H_ */
162