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

Side by Side Diff: nss/lib/pkcs7/certread.c

Issue 13898013: Update NSS to NSS_3_15_BETA2. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/deps/third_party/nss/
Patch Set: Update NSS versions and tag in README.chromium Created 7 years, 8 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 | Annotate | Revision Log
OLDNEW
1 /* This Source Code Form is subject to the terms of the Mozilla Public 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 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/. */ 3 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
4 4
5 #include "cert.h" 5 #include "cert.h"
6 #include "secpkcs7.h"
7 #include "base64.h" 6 #include "base64.h"
8 #include "secitem.h" 7 #include "secitem.h"
9 #include "secder.h" 8 #include "secder.h"
10 #include "secasn1.h" 9 #include "secasn1.h"
11 #include "secoid.h" 10 #include "secoid.h"
12 #include "secerr.h" 11 #include "secerr.h"
13 12
14 SEC_ASN1_MKSUB(SEC_AnyTemplate) 13 SEC_ASN1_MKSUB(SEC_AnyTemplate)
14 SEC_ASN1_MKSUB(SEC_SetOfAnyTemplate)
15 15
16 SECStatus 16 typedef struct ContentInfoStr ContentInfo;
17 typedef struct DegenerateSignedDataStr DegenerateSignedData;
18
19 struct ContentInfoStr {
20 SECOidTag contentTypeTag; /* local; not part of encoding */
21 SECItem contentType;
22 union {
23 SECItem *data;
24 DegenerateSignedData *signedData;
25 } content;
26 };
27
28 struct DegenerateSignedDataStr {
29 SECItem version;
30 SECItem **digestAlgorithms;
31 ContentInfo contentInfo;
32 SECItem **certificates;
33 SECItem **crls;
34 SECItem **signerInfos;
35 };
36
37 static const SEC_ASN1Template *
38 choose_content_template(void *src_or_dest, PRBool encoding);
39
40 static const SEC_ASN1TemplateChooserPtr template_chooser
41 = choose_content_template;
42
43 static const SEC_ASN1Template ContentInfoTemplate[] = {
44 { SEC_ASN1_SEQUENCE,
45 0, NULL, sizeof(ContentInfo) },
46 { SEC_ASN1_OBJECT_ID,
47 offsetof(ContentInfo,contentType) },
48 { SEC_ASN1_OPTIONAL | SEC_ASN1_DYNAMIC |
49 SEC_ASN1_EXPLICIT | SEC_ASN1_CONSTRUCTED | SEC_ASN1_CONTEXT_SPECIFIC | 0,
50 offsetof(ContentInfo,content),
51 &template_chooser },
52 { 0 }
53 };
54
55 static const SEC_ASN1Template DegenerateSignedDataTemplate[] = {
56 { SEC_ASN1_SEQUENCE,
57 0, NULL, sizeof(DegenerateSignedData) },
58 { SEC_ASN1_INTEGER,
59 offsetof(DegenerateSignedData,version) },
60 { SEC_ASN1_SET_OF | SEC_ASN1_XTRN,
61 offsetof(DegenerateSignedData,digestAlgorithms),
62 SEC_ASN1_SUB(SEC_AnyTemplate) },
63 { SEC_ASN1_INLINE,
64 offsetof(DegenerateSignedData,contentInfo),
65 ContentInfoTemplate },
66 { SEC_ASN1_OPTIONAL | SEC_ASN1_CONSTRUCTED | SEC_ASN1_CONTEXT_SPECIFIC |
67 SEC_ASN1_XTRN | 0,
68 offsetof(DegenerateSignedData,certificates),
69 SEC_ASN1_SUB(SEC_SetOfAnyTemplate) },
70 { SEC_ASN1_OPTIONAL | SEC_ASN1_CONSTRUCTED | SEC_ASN1_CONTEXT_SPECIFIC |
71 SEC_ASN1_XTRN | 1,
72 offsetof(DegenerateSignedData,crls),
73 SEC_ASN1_SUB(SEC_SetOfAnyTemplate) },
74 { SEC_ASN1_SET_OF | SEC_ASN1_XTRN,
75 offsetof(DegenerateSignedData,signerInfos),
76 SEC_ASN1_SUB(SEC_AnyTemplate) },
77 { 0 }
78 };
79
80 static const SEC_ASN1Template PointerToDegenerateSignedDataTemplate[] = {
81 { SEC_ASN1_POINTER, 0, DegenerateSignedDataTemplate }
82 };
83
84 static SECOidTag
85 GetContentTypeTag(ContentInfo *cinfo)
86 {
87 if (cinfo->contentTypeTag == SEC_OID_UNKNOWN)
88 cinfo->contentTypeTag = SECOID_FindOIDTag(&cinfo->contentType);
89 return cinfo->contentTypeTag;
90 }
91
92 static const SEC_ASN1Template *
93 choose_content_template(void *src_or_dest, PRBool encoding)
94 {
95 const SEC_ASN1Template *theTemplate;
96 ContentInfo *cinfo;
97 SECOidTag kind;
98
99 PORT_Assert(src_or_dest != NULL);
100 if (src_or_dest == NULL)
101 return NULL;
102
103 cinfo = (ContentInfo*)src_or_dest;
104 kind = GetContentTypeTag(cinfo);
105 switch (kind) {
106 default:
107 theTemplate = SEC_ASN1_GET(SEC_PointerToAnyTemplate);
108 break;
109 case SEC_OID_PKCS7_DATA:
110 theTemplate = SEC_ASN1_GET(SEC_PointerToOctetStringTemplate);
111 break;
112 case SEC_OID_PKCS7_SIGNED_DATA:
113 theTemplate = PointerToDegenerateSignedDataTemplate;
114 break;
115 }
116 return theTemplate;
117 }
118
119 static SECStatus
17 SEC_ReadPKCS7Certs(SECItem *pkcs7Item, CERTImportCertificateFunc f, void *arg) 120 SEC_ReadPKCS7Certs(SECItem *pkcs7Item, CERTImportCertificateFunc f, void *arg)
18 { 121 {
19 SEC_PKCS7ContentInfo *contentInfo = NULL; 122 ContentInfo contentInfo;
20 SECStatus rv; 123 SECStatus rv;
21 SECItem **certs; 124 SECItem **certs;
22 int count; 125 int count;
126 PRArenaPool *arena;
23 127
24 contentInfo = SEC_PKCS7DecodeItem(pkcs7Item, NULL, NULL, NULL, NULL, NULL, 128 arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
25 » » » » NULL, NULL); 129 if ( arena == NULL ) {
26 if ( contentInfo == NULL ) { 130 » return SECFailure;
131 }
132
133 PORT_Memset(&contentInfo, 0, sizeof(contentInfo));
134 rv = SEC_ASN1DecodeItem(arena, &contentInfo, ContentInfoTemplate,
135 » » » pkcs7Item);
136 if ( rv != SECSuccess ) {
27 goto loser; 137 goto loser;
28 } 138 }
29 139
30 if ( SEC_PKCS7ContentType (contentInfo) != SEC_OID_PKCS7_SIGNED_DATA ) { 140 if ( GetContentTypeTag(&contentInfo) != SEC_OID_PKCS7_SIGNED_DATA ) {
31 goto loser; 141 goto loser;
32 } 142 }
33 143
34 certs = contentInfo->content.signedData->rawCerts; 144 certs = contentInfo.content.signedData->certificates;
35 if ( certs ) { 145 if ( certs ) {
36 count = 0; 146 count = 0;
37 147
38 while ( *certs ) { 148 while ( *certs ) {
39 count++; 149 count++;
40 certs++; 150 certs++;
41 } 151 }
42 » rv = (* f)(arg, contentInfo->content.signedData->rawCerts, count); 152 » rv = (* f)(arg, contentInfo.content.signedData->certificates, count);
43 } 153 }
44 154
45 rv = SECSuccess; 155 rv = SECSuccess;
46 156
47 goto done; 157 goto done;
48 loser: 158 loser:
49 rv = SECFailure; 159 rv = SECFailure;
50 160
51 done: 161 done:
52 if ( contentInfo ) { 162 if ( arena ) {
53 » SEC_PKCS7DestroyContentInfo(contentInfo); 163 » PORT_FreeArena(arena, PR_FALSE);
54 } 164 }
55 165
56 return(rv); 166 return(rv);
57 } 167 }
58 168
59 const SEC_ASN1Template SEC_CertSequenceTemplate[] = { 169 const SEC_ASN1Template SEC_CertSequenceTemplate[] = {
60 { SEC_ASN1_SEQUENCE_OF | SEC_ASN1_XTRN, 0, SEC_ASN1_SUB(SEC_AnyTemplate) } 170 { SEC_ASN1_SEQUENCE_OF | SEC_ASN1_XTRN, 0, SEC_ASN1_SUB(SEC_AnyTemplate) }
61 }; 171 };
62 172
63 SECStatus 173 static SECStatus
64 SEC_ReadCertSequence(SECItem *certsItem, CERTImportCertificateFunc f, void *arg) 174 SEC_ReadCertSequence(SECItem *certsItem, CERTImportCertificateFunc f, void *arg)
65 { 175 {
66 SECStatus rv; 176 SECStatus rv;
67 SECItem **certs; 177 SECItem **certs;
68 int count; 178 int count;
69 SECItem **rawCerts = NULL; 179 SECItem **rawCerts = NULL;
70 PRArenaPool *arena; 180 PRArenaPool *arena;
71 SEC_PKCS7ContentInfo *contentInfo = NULL; 181 ContentInfo contentInfo;
72 182
73 arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE); 183 arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
74 if (arena == NULL) { 184 if ( arena == NULL ) {
75 return SECFailure; 185 return SECFailure;
76 } 186 }
77 187
78 contentInfo = SEC_PKCS7DecodeItem(certsItem, NULL, NULL, NULL, NULL, NULL, 188 PORT_Memset(&contentInfo, 0, sizeof(contentInfo));
79 » » » » NULL, NULL); 189 rv = SEC_ASN1DecodeItem(arena, &contentInfo, ContentInfoTemplate,
80 if ( contentInfo == NULL ) { 190 » » » certsItem);
191 if ( rv != SECSuccess ) {
81 goto loser; 192 goto loser;
82 } 193 }
83 194
84 if ( SEC_PKCS7ContentType (contentInfo) != SEC_OID_NS_TYPE_CERT_SEQUENCE ) { 195 if ( GetContentTypeTag(&contentInfo) != SEC_OID_NS_TYPE_CERT_SEQUENCE ) {
85 goto loser; 196 goto loser;
86 } 197 }
87 198
88
89 rv = SEC_QuickDERDecodeItem(arena, &rawCerts, SEC_CertSequenceTemplate, 199 rv = SEC_QuickDERDecodeItem(arena, &rawCerts, SEC_CertSequenceTemplate,
90 » » contentInfo->content.data); 200 » » contentInfo.content.data);
91 201
92 if (rv != SECSuccess) { 202 if (rv != SECSuccess) {
93 goto loser; 203 goto loser;
94 } 204 }
95 205
96 certs = rawCerts; 206 certs = rawCerts;
97 if ( certs ) { 207 if ( certs ) {
98 count = 0; 208 count = 0;
99 209
100 while ( *certs ) { 210 while ( *certs ) {
101 count++; 211 count++;
102 certs++; 212 certs++;
103 } 213 }
104 rv = (* f)(arg, rawCerts, count); 214 rv = (* f)(arg, rawCerts, count);
105 } 215 }
106 216
107 rv = SECSuccess; 217 rv = SECSuccess;
108 218
109 goto done; 219 goto done;
110 loser: 220 loser:
111 rv = SECFailure; 221 rv = SECFailure;
112 222
113 done: 223 done:
114 if ( contentInfo ) {
115 SEC_PKCS7DestroyContentInfo(contentInfo);
116 }
117
118 if ( arena ) { 224 if ( arena ) {
119 PORT_FreeArena(arena, PR_FALSE); 225 PORT_FreeArena(arena, PR_FALSE);
120 } 226 }
121 227
122 return(rv); 228 return(rv);
123 } 229 }
124 230
125 CERTCertificate * 231 CERTCertificate *
126 CERT_ConvertAndDecodeCertificate(char *certstr) 232 CERT_ConvertAndDecodeCertificate(char *certstr)
127 { 233 {
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
161 267
162 if ( certbuf == NULL ) { 268 if ( certbuf == NULL ) {
163 PORT_SetError(SEC_ERROR_INVALID_ARGS); 269 PORT_SetError(SEC_ERROR_INVALID_ARGS);
164 return(SECFailure); 270 return(SECFailure);
165 } 271 }
166 /* 272 /*
167 * Make sure certlen is long enough to handle the longest possible 273 * Make sure certlen is long enough to handle the longest possible
168 * reference in the code below: 274 * reference in the code below:
169 * 0x30 0x84 l1 l2 l3 l4 + 275 * 0x30 0x84 l1 l2 l3 l4 +
170 * tag 9 o1 o2 o3 o4 o5 o6 o7 o8 o9 276 * tag 9 o1 o2 o3 o4 o5 o6 o7 o8 o9
277 * where 9 is the longest length of the expected oids we are testing.
171 * 6 + 11 = 17. 17 bytes is clearly too small to code any kind of 278 * 6 + 11 = 17. 17 bytes is clearly too small to code any kind of
172 * certificate (a 128 bit ECC certificate contains at least an 8 byte 279 * certificate (a 128 bit ECC certificate contains at least an 8 byte
173 * key and a 16 byte signature, plus coding overhead). Typically a cert 280 * key and a 16 byte signature, plus coding overhead). Typically a cert
174 * is much larger. So it's safe to require certlen to be at least 17 281 * is much larger. So it's safe to require certlen to be at least 17
175 * bytes. 282 * bytes.
176 */ 283 */
177 if (certlen < 17) { 284 if (certlen < 17) {
178 PORT_SetError(SEC_ERROR_INPUT_LEN); 285 PORT_SetError(SEC_ERROR_INPUT_LEN);
179 return(SECFailure); 286 return(SECFailure);
180 } 287 }
(...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after
251 oiddata = SECOID_FindOID(&oiditem); 358 oiddata = SECOID_FindOID(&oiditem);
252 if ( oiddata == NULL ) { 359 if ( oiddata == NULL ) {
253 return(SECFailure); 360 return(SECFailure);
254 } 361 }
255 362
256 certitem.data = (unsigned char*)certbuf; 363 certitem.data = (unsigned char*)certbuf;
257 certitem.len = certlen; 364 certitem.len = certlen;
258 365
259 switch ( oiddata->offset ) { 366 switch ( oiddata->offset ) {
260 case SEC_OID_PKCS7_SIGNED_DATA: 367 case SEC_OID_PKCS7_SIGNED_DATA:
368 /* oid: 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x07, 0x02 */
261 return(SEC_ReadPKCS7Certs(&certitem, f, arg)); 369 return(SEC_ReadPKCS7Certs(&certitem, f, arg));
262 break; 370 break;
263 case SEC_OID_NS_TYPE_CERT_SEQUENCE: 371 case SEC_OID_NS_TYPE_CERT_SEQUENCE:
372 /* oid: 0x60, 0x86, 0x48, 0x01, 0x86, 0xf8, 0x42, 0x02, 0x05 */
264 return(SEC_ReadCertSequence(&certitem, f, arg)); 373 return(SEC_ReadCertSequence(&certitem, f, arg));
265 break; 374 break;
266 default: 375 default:
267 break; 376 break;
268 } 377 }
269 378
270 } else { 379 } else {
271 /* it had better be a certificate by now!! */ 380 /* it had better be a certificate by now!! */
272 certitem.data = (unsigned char*)certbuf; 381 certitem.data = (unsigned char*)certbuf;
273 certitem.len = certlen; 382 certitem.len = certlen;
(...skipping 151 matching lines...) Expand 10 before | Expand all | Expand 10 after
425 if ( rv == SECSuccess ) { 534 if ( rv == SECSuccess ) {
426 cert = CERT_NewTempCertificate(CERT_GetDefaultCertDB(), 535 cert = CERT_NewTempCertificate(CERT_GetDefaultCertDB(),
427 &collectArgs.cert, NULL, 536 &collectArgs.cert, NULL,
428 PR_FALSE, PR_TRUE); 537 PR_FALSE, PR_TRUE);
429 } 538 }
430 539
431 PORT_FreeArena(collectArgs.arena, PR_FALSE); 540 PORT_FreeArena(collectArgs.arena, PR_FALSE);
432 541
433 return(cert); 542 return(cert);
434 } 543 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698