]> git.saurik.com Git - apple/security.git/blob - AppleX509CL/DecodedCert.h
Security-54.1.3.tar.gz
[apple/security.git] / AppleX509CL / DecodedCert.h
1 /*
2 * Copyright (c) 2000-2001 Apple Computer, Inc. All Rights Reserved.
3 *
4 * The contents of this file constitute Original Code as defined in and are
5 * subject to the Apple Public Source License Version 1.2 (the 'License').
6 * You may not use this file except in compliance with the License. Please obtain
7 * a copy of the License at http://www.apple.com/publicsource and read it before
8 * using this file.
9 *
10 * This Original Code and all software distributed under the License are
11 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS
12 * OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, INCLUDING WITHOUT
13 * LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
14 * PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. Please see the License for the
15 * specific language governing rights and limitations under the License.
16 */
17
18
19 /*
20 * DecodedCert.h - object representing a snacc-decoded cert, with extensions
21 * parsed and decoded (still in snacc format).
22 *
23 * Created 9/1/2000 by Doug Mitchell.
24 * Copyright (c) 2000 by Apple Computer.
25 *
26 * This object is how we store certs, both when caching them (explicitly or
27 * during a search), and as an intermediate stage during template (TBS, or
28 * to-be-signed cert) construction. This is a subclass of the SNACC-generated class
29 * Certificate; the main functionality we add is the parsing and decoding of
30 * Extensions. Extensions are not decoded in class Certificate beyond the level
31 * of the X.509 Extension object, which just contains the ID (an OID), the
32 * critical flag, and an octet string containing an ID-specific thing.
33 *
34 * When we decode a cert or a TBS, we also parse the Extension objects, decoding
35 * then into specific SNACC classes like KeyUsage or BasicConstriantsSyntax. We
36 * keep these decoded extensions in a list of DecodedExten structs. GetCertField
37 * ops which access extensions access these DecodedExten structs.
38 *
39 * When creating a cert template (TBS), each incoming field associated with an
40 * extension is translated into an object like a (SNACC) KeyUsage and stored in
41 * our DecodedExten list.
42 *
43 * When encoding a TBS, we BER-encode each of the SNACC objects (KeyUsage, etc.)
44 * in our list of DecodedExtens, wrapthe result in an Octet string (actually an
45 * AsnOcts) and store it in the SNACC-generated CertificateToSign's extensions
46 * list.
47 *
48 * Support for extensions which we don't understand is handled as follows. When
49 * setting cert fields for such extensions during template construction, the app
50 * has to BER-encode the underlying extension. We just wrap this in an octet string
51 * (AsnOcts) and store the result in a DecodedExten without further ado. When
52 * encoding the TBS, this octet string is just copied into the CertificateToSign's
53 * Extension list without further ado. When decoding a cert, if we find an
54 * extension we don't understand, the SNACC object stored in the DecodedExten
55 * is just a copy of the AsnOcts (which is the BER encoding of the underlying
56 * mystery extension wrapped in an Octet string). We pass back the Octet string's
57 * contents (*not* the BER-encoded octet string) during a GetCertField op.
58 */
59
60 #ifndef _DECODED_CERT_H_
61 #define _DECODED_CERT_H_
62
63 #include <Security/cssmtype.h>
64 #include <Security/cssmdata.h>
65
66 #include <Security/asn-incl.h>
67 #include <Security/sm_vdatypes.h>
68 #include <Security/sm_x501if.h>
69 #include <Security/sm_x520sa.h>
70 #include <Security/sm_x411mtsas.h>
71 #include <Security/sm_x509cmn.h>
72 #include <Security/sm_x509af.h>
73 #include <Security/pkcs9oids.h>
74 #include <Security/sm_x509ce.h>
75 #include <Security/sm_cms.h>
76 #include <Security/sm_ess.h>
77
78 /* state of a DecodedCert */
79 typedef enum {
80 CS_Empty,
81 CS_DecodedCert, // can't set fields in this state
82 CS_DecodedTBS, // ditto
83 CS_Building // in the process of setting fields
84 } CertState;
85
86 /* means for holding decoded extensions */
87 typedef struct {
88 AsnOid *extnId;
89 bool critical;
90 AsnType *snaccObj; // KeyUsage, BasicConstraintsSyntax, etc.
91 bool berEncoded; // indicates unknown extension which we
92 // do not BER-decode when parsing a cert
93 } DecodedExten;
94
95 class AppleX509CLSession;
96
97 class DecodedCert : public Certificate
98 {
99 public:
100 /* construct empty cert, no decoded extensions */
101 DecodedCert(
102 AppleX509CLSession &session);
103
104 /* one-shot constructor, decoding from DER-encoded data */
105 DecodedCert(
106 AppleX509CLSession &session,
107 const CssmData &encodedCert);
108
109 ~DecodedCert();
110
111 /* decode TBSCert and its extensions */
112 void decodeTbs(
113 const CssmData &encodedTbs);
114
115 /* encode TBSCert and its extensions */
116 void encodeTbs(
117 CssmOwnedData &encodedTbs);
118
119 /***
120 *** field accessors (in CertFields.cpp)
121 ***/
122
123 /*
124 * Obtain the index'th occurrence of field specified by fieldId.
125 * Format of the returned field depends on fieldId.
126 * Returns total number of fieldId fields in the cert if index is 0.
127 * Returns true if specified field was found, else returns false.
128 */
129 bool getCertFieldData(
130 const CssmOid &fieldId, // which field
131 unsigned index, // which occurrence (0 = first)
132 uint32 &numFields, // RETURNED
133 CssmOwnedData &fieldValue) const; // RETURNED
134
135 /*
136 * Set the field specified by fieldId in TBS.
137 * Note no index - individual field routines either append (for extensions)
138 * or throw if field already set (for all others)
139 */
140 void setCertField(
141 const CssmOid &fieldId, // which field
142 const CssmData &fieldValue);
143
144 /*
145 * Free the fieldId-specific data referred to by fieldValue.get().data().
146 */
147 static void freeCertFieldData(
148 const CssmOid &fieldId,
149 CssmOwnedData &fieldValue);
150
151 void getAllParsedCertFields(
152 uint32 &NumberOfFields, // RETURNED
153 CSSM_FIELD_PTR &CertFields); // RETURNED
154
155 static void describeFormat(
156 CssmAllocator &alloc,
157 uint32 &NumberOfFields,
158 CSSM_OID_PTR &OidList);
159
160 /*
161 * Obtain a CSSM_KEY from a decoded cert, inferring as much as we can
162 * from required fields (subjectPublicKeyInfo) and extensions (for
163 * KeyUse).
164 */
165 CSSM_KEY_PTR extractCSSMKey(
166 CssmAllocator &alloc) const;
167
168 CSSM_KEYUSE inferKeyUsage() const;
169
170 private:
171
172 /***
173 *** Extensions support (CertExtensions.cpp)
174 ***/
175
176 /* decode extensions ==> mExtensions */
177 void decodeExtensions();
178
179 /* encode mExtensions ==> tbs->Extensions */
180 void encodeExtensions();
181
182 /* called from decodeExtensions and setField* */
183 void addExtension(
184 AsnType *snaccThing, // e.g. KeyUsage
185 const AsnOid &extnId,
186 bool critical,
187 bool berEncoded);
188
189 public:
190
191 /* as above, CSSM-centric OID */
192 void addExtension(
193 AsnType *snaccThing, // e.g. KeyUsage
194 const CSSM_OID &extnId,
195 bool critical,
196 bool berEncoded)
197 {
198 AsnOid snaccOid(reinterpret_cast<char *>(extnId.Data), extnId.Length);
199 addExtension(snaccThing, snaccOid, critical, berEncoded);
200 }
201
202 /* called from getField* and inferKeyUsage */
203 /* returns NULL if not found */
204 DecodedExten *findDecodedExt(
205 const AsnOid &extnId, // for known extensions
206 bool unknown, // otherwise
207 uint32 index,
208 uint32 &numFields) const;
209
210 private:
211 CertState mState;
212 DecodedExten *mExtensions;
213 unsigned mNumExtensions; // # valid DecodedExtens
214 unsigned mSizeofExtensions; // mallocd size in DecodedExten
215 CssmAllocator &alloc;
216 AppleX509CLSession &mSession;
217
218 void reset()
219 {
220 mState = CS_Empty;
221 mExtensions = NULL;
222 mNumExtensions = 0;
223 mSizeofExtensions = 0;
224 }
225 };
226
227 #endif /* _DECODED_CERT_H_ */