Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(255)

Side by Side Diff: nss/lib/certhigh/certreq.c

Issue 2078763002: Delete bundled copy of NSS and replace with README. (Closed) Base URL: https://chromium.googlesource.com/chromium/deps/nss@master
Patch Set: Delete bundled copy of NSS and replace with README. Created 4 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « nss/lib/certhigh/certhtml.c ('k') | nss/lib/certhigh/certvfy.c » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
1 /* This Source Code Form is subject to the terms of the Mozilla Public
2 * License, v. 2.0. If a copy of the MPL was not distributed with this
3 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
4
5 #include "cert.h"
6 #include "certt.h"
7 #include "secder.h"
8 #include "key.h"
9 #include "secitem.h"
10 #include "secasn1.h"
11 #include "secerr.h"
12
13 SEC_ASN1_MKSUB(SEC_AnyTemplate)
14
15 const SEC_ASN1Template CERT_AttributeTemplate[] = {
16 { SEC_ASN1_SEQUENCE,
17 0, NULL, sizeof(CERTAttribute) },
18 { SEC_ASN1_OBJECT_ID, offsetof(CERTAttribute, attrType) },
19 { SEC_ASN1_SET_OF | SEC_ASN1_XTRN, offsetof(CERTAttribute, attrValue),
20 SEC_ASN1_SUB(SEC_AnyTemplate) },
21 { 0 }
22 };
23
24 const SEC_ASN1Template CERT_SetOfAttributeTemplate[] = {
25 { SEC_ASN1_SET_OF, 0, CERT_AttributeTemplate },
26 };
27
28 const SEC_ASN1Template CERT_CertificateRequestTemplate[] = {
29 { SEC_ASN1_SEQUENCE,
30 0, NULL, sizeof(CERTCertificateRequest) },
31 { SEC_ASN1_INTEGER,
32 offsetof(CERTCertificateRequest, version) },
33 { SEC_ASN1_INLINE,
34 offsetof(CERTCertificateRequest, subject),
35 CERT_NameTemplate },
36 { SEC_ASN1_INLINE,
37 offsetof(CERTCertificateRequest, subjectPublicKeyInfo),
38 CERT_SubjectPublicKeyInfoTemplate },
39 { SEC_ASN1_CONSTRUCTED | SEC_ASN1_CONTEXT_SPECIFIC | 0,
40 offsetof(CERTCertificateRequest, attributes),
41 CERT_SetOfAttributeTemplate },
42 { 0 }
43 };
44
45 SEC_ASN1_CHOOSER_IMPLEMENT(CERT_CertificateRequestTemplate)
46
47 CERTCertificate *
48 CERT_CreateCertificate(unsigned long serialNumber,
49 CERTName *issuer,
50 CERTValidity *validity,
51 CERTCertificateRequest *req)
52 {
53 CERTCertificate *c;
54 int rv;
55 PLArenaPool *arena;
56
57 arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
58
59 if (!arena) {
60 return (0);
61 }
62
63 c = (CERTCertificate *)PORT_ArenaZAlloc(arena, sizeof(CERTCertificate));
64
65 if (!c) {
66 PORT_FreeArena(arena, PR_FALSE);
67 return 0;
68 }
69
70 c->referenceCount = 1;
71 c->arena = arena;
72
73 /*
74 * Default is a plain version 1.
75 * If extensions are added, it will get changed as appropriate.
76 */
77 rv = DER_SetUInteger(arena, &c->version, SEC_CERTIFICATE_VERSION_1);
78 if (rv)
79 goto loser;
80
81 rv = DER_SetUInteger(arena, &c->serialNumber, serialNumber);
82 if (rv)
83 goto loser;
84
85 rv = CERT_CopyName(arena, &c->issuer, issuer);
86 if (rv)
87 goto loser;
88
89 rv = CERT_CopyValidity(arena, &c->validity, validity);
90 if (rv)
91 goto loser;
92
93 rv = CERT_CopyName(arena, &c->subject, &req->subject);
94 if (rv)
95 goto loser;
96 rv = SECKEY_CopySubjectPublicKeyInfo(arena, &c->subjectPublicKeyInfo,
97 &req->subjectPublicKeyInfo);
98 if (rv)
99 goto loser;
100
101 return c;
102
103 loser:
104 CERT_DestroyCertificate(c);
105 return 0;
106 }
107
108 /************************************************************************/
109 /* It's clear from the comments that the original author of this
110 * function expected the template for certificate requests to treat
111 * the attributes as a SET OF ANY. This function expected to be
112 * passed an array of SECItems each of which contained an already encoded
113 * Attribute. But the cert request template does not treat the
114 * Attributes as a SET OF ANY, and AFAIK never has. Instead the template
115 * encodes attributes as a SET OF xxxxxxx. That is, it expects to encode
116 * each of the Attributes, not have them pre-encoded. Consequently an
117 * array of SECItems containing encoded Attributes is of no value to this
118 * function. But we cannot change the signature of this public function.
119 * It must continue to take SECItems.
120 *
121 * I have recoded this function so that each SECItem contains an
122 * encoded cert extension. The encoded cert extensions form the list for the
123 * single attribute of the cert request. In this implementation there is at most
124 * one attribute and it is always of type SEC_OID_PKCS9_EXTENSION_REQUEST.
125 */
126
127 CERTCertificateRequest *
128 CERT_CreateCertificateRequest(CERTName *subject,
129 CERTSubjectPublicKeyInfo *spki,
130 SECItem **attributes)
131 {
132 CERTCertificateRequest *certreq;
133 PLArenaPool *arena;
134 CERTAttribute *attribute;
135 SECOidData *oidData;
136 SECStatus rv;
137 int i = 0;
138
139 arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
140 if (arena == NULL) {
141 return NULL;
142 }
143
144 certreq = PORT_ArenaZNew(arena, CERTCertificateRequest);
145 if (!certreq) {
146 PORT_FreeArena(arena, PR_FALSE);
147 return NULL;
148 }
149 /* below here it is safe to goto loser */
150
151 certreq->arena = arena;
152
153 rv = DER_SetUInteger(arena, &certreq->version,
154 SEC_CERTIFICATE_REQUEST_VERSION);
155 if (rv != SECSuccess)
156 goto loser;
157
158 rv = CERT_CopyName(arena, &certreq->subject, subject);
159 if (rv != SECSuccess)
160 goto loser;
161
162 rv = SECKEY_CopySubjectPublicKeyInfo(arena,
163 &certreq->subjectPublicKeyInfo,
164 spki);
165 if (rv != SECSuccess)
166 goto loser;
167
168 certreq->attributes = PORT_ArenaZNewArray(arena, CERTAttribute *, 2);
169 if (!certreq->attributes)
170 goto loser;
171
172 /* Copy over attribute information */
173 if (!attributes || !attributes[0]) {
174 /*
175 ** Invent empty attribute information. According to the
176 ** pkcs#10 spec, attributes has this ASN.1 type:
177 **
178 ** attributes [0] IMPLICIT Attributes
179 **
180 ** Which means, we should create a NULL terminated list
181 ** with the first entry being NULL;
182 */
183 certreq->attributes[0] = NULL;
184 return certreq;
185 }
186
187 /* allocate space for attributes */
188 attribute = PORT_ArenaZNew(arena, CERTAttribute);
189 if (!attribute)
190 goto loser;
191
192 oidData = SECOID_FindOIDByTag(SEC_OID_PKCS9_EXTENSION_REQUEST);
193 PORT_Assert(oidData);
194 if (!oidData)
195 goto loser;
196 rv = SECITEM_CopyItem(arena, &attribute->attrType, &oidData->oid);
197 if (rv != SECSuccess)
198 goto loser;
199
200 for (i = 0; attributes[i] != NULL; i++)
201 ;
202 attribute->attrValue = PORT_ArenaZNewArray(arena, SECItem *, i + 1);
203 if (!attribute->attrValue)
204 goto loser;
205
206 /* copy attributes */
207 for (i = 0; attributes[i]; i++) {
208 /*
209 ** Attributes are a SetOf Attribute which implies
210 ** lexigraphical ordering. It is assumes that the
211 ** attributes are passed in sorted. If we need to
212 ** add functionality to sort them, there is an
213 ** example in the PKCS 7 code.
214 */
215 attribute->attrValue[i] = SECITEM_ArenaDupItem(arena, attributes[i]);
216 if (!attribute->attrValue[i])
217 goto loser;
218 }
219
220 certreq->attributes[0] = attribute;
221
222 return certreq;
223
224 loser:
225 CERT_DestroyCertificateRequest(certreq);
226 return NULL;
227 }
228
229 void
230 CERT_DestroyCertificateRequest(CERTCertificateRequest *req)
231 {
232 if (req && req->arena) {
233 PORT_FreeArena(req->arena, PR_FALSE);
234 }
235 return;
236 }
237
238 static void
239 setCRExt(void *o, CERTCertExtension **exts)
240 {
241 ((CERTCertificateRequest *)o)->attributes = (struct CERTAttributeStr **)exts ;
242 }
243
244 /*
245 ** Set up to start gathering cert extensions for a cert request.
246 ** The list is created as CertExtensions and converted to an
247 ** attribute list by CERT_FinishCRAttributes().
248 */
249 extern void *cert_StartExtensions(void *owner, PLArenaPool *ownerArena,
250 void (*setExts)(void *object, CERTCertExtensio n **exts));
251 void *
252 CERT_StartCertificateRequestAttributes(CERTCertificateRequest *req)
253 {
254 return (cert_StartExtensions((void *)req, req->arena, setCRExt));
255 }
256
257 /*
258 ** At entry req->attributes actually contains an list of cert extensions--
259 ** req-attributes is overloaded until the list is DER encoded (the first
260 ** ...EncodeItem() below).
261 ** We turn this into an attribute list by encapsulating it
262 ** in a PKCS 10 Attribute structure
263 */
264 SECStatus
265 CERT_FinishCertificateRequestAttributes(CERTCertificateRequest *req)
266 {
267 SECItem *extlist;
268 SECOidData *oidrec;
269 CERTAttribute *attribute;
270
271 if (!req || !req->arena) {
272 PORT_SetError(SEC_ERROR_INVALID_ARGS);
273 return SECFailure;
274 }
275 if (req->attributes == NULL || req->attributes[0] == NULL)
276 return SECSuccess;
277
278 extlist = SEC_ASN1EncodeItem(req->arena, NULL, &req->attributes,
279 SEC_ASN1_GET(CERT_SequenceOfCertExtensionTempla te));
280 if (extlist == NULL)
281 return (SECFailure);
282
283 oidrec = SECOID_FindOIDByTag(SEC_OID_PKCS9_EXTENSION_REQUEST);
284 if (oidrec == NULL)
285 return SECFailure;
286
287 /* now change the list of cert extensions into a list of attributes
288 */
289 req->attributes = PORT_ArenaZNewArray(req->arena, CERTAttribute *, 2);
290
291 attribute = PORT_ArenaZNew(req->arena, CERTAttribute);
292
293 if (req->attributes == NULL || attribute == NULL ||
294 SECITEM_CopyItem(req->arena, &attribute->attrType, &oidrec->oid) != 0) {
295 PORT_SetError(SEC_ERROR_NO_MEMORY);
296 return SECFailure;
297 }
298 attribute->attrValue = PORT_ArenaZNewArray(req->arena, SECItem *, 2);
299
300 if (attribute->attrValue == NULL)
301 return SECFailure;
302
303 attribute->attrValue[0] = extlist;
304 attribute->attrValue[1] = NULL;
305 req->attributes[0] = attribute;
306 req->attributes[1] = NULL;
307
308 return SECSuccess;
309 }
310
311 SECStatus
312 CERT_GetCertificateRequestExtensions(CERTCertificateRequest *req,
313 CERTCertExtension ***exts)
314 {
315 if (req == NULL || exts == NULL) {
316 PORT_SetError(SEC_ERROR_INVALID_ARGS);
317 return SECFailure;
318 }
319
320 if (req->attributes == NULL || *req->attributes == NULL)
321 return SECSuccess;
322
323 if ((*req->attributes)->attrValue == NULL) {
324 PORT_SetError(SEC_ERROR_INVALID_ARGS);
325 return SECFailure;
326 }
327
328 return (SEC_ASN1DecodeItem(req->arena, exts,
329 SEC_ASN1_GET(CERT_SequenceOfCertExtensionTemplate ),
330 (*req->attributes)->attrValue[0]));
331 }
OLDNEW
« no previous file with comments | « nss/lib/certhigh/certhtml.c ('k') | nss/lib/certhigh/certvfy.c » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698