OLD | NEW |
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 /* | 5 /* |
6 * Code for dealing with X509.V3 extensions. | 6 * Code for dealing with X509.V3 extensions. |
7 */ | 7 */ |
8 | 8 |
9 #include "cert.h" | 9 #include "cert.h" |
10 #include "secitem.h" | 10 #include "secitem.h" |
(...skipping 25 matching lines...) Expand all Loading... |
36 cert->extensions = exts; | 36 cert->extensions = exts; |
37 DER_SetUInteger (cert->arena, &(cert->version), SEC_CERTIFICATE_VERSION_3); | 37 DER_SetUInteger (cert->arena, &(cert->version), SEC_CERTIFICATE_VERSION_3); |
38 } | 38 } |
39 | 39 |
40 void * | 40 void * |
41 CERT_StartCertExtensions(CERTCertificate *cert) | 41 CERT_StartCertExtensions(CERTCertificate *cert) |
42 { | 42 { |
43 return (cert_StartExtensions ((void *)cert, cert->arena, SetExts)); | 43 return (cert_StartExtensions ((void *)cert, cert->arena, SetExts)); |
44 } | 44 } |
45 | 45 |
46 /* find the given extension in the certificate of the Issuer of 'cert' */ | |
47 SECStatus | |
48 CERT_FindIssuerCertExtension(CERTCertificate *cert, int tag, SECItem *value) | |
49 { | |
50 CERTCertificate *issuercert; | |
51 SECStatus rv; | |
52 | |
53 issuercert = CERT_FindCertByName(cert->dbhandle, &cert->derIssuer); | |
54 if ( issuercert ) { | |
55 rv = cert_FindExtension(issuercert->extensions, tag, value); | |
56 CERT_DestroyCertificate(issuercert); | |
57 } else { | |
58 rv = SECFailure; | |
59 } | |
60 | |
61 return(rv); | |
62 } | |
63 | |
64 /* find a URL extension in the cert or its CA | |
65 * apply the base URL string if it exists | |
66 */ | |
67 char * | |
68 CERT_FindCertURLExtension(CERTCertificate *cert, int tag, int catag) | |
69 { | |
70 SECStatus rv; | |
71 SECItem urlitem = {siBuffer,0}; | |
72 SECItem baseitem = {siBuffer,0}; | |
73 SECItem urlstringitem = {siBuffer,0}; | |
74 SECItem basestringitem = {siBuffer,0}; | |
75 PLArenaPool *arena = NULL; | |
76 PRBool hasbase; | |
77 char *urlstring; | |
78 char *str; | |
79 int len; | |
80 unsigned int i; | |
81 | |
82 urlstring = NULL; | |
83 | |
84 arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE); | |
85 if ( ! arena ) { | |
86 goto loser; | |
87 } | |
88 | |
89 hasbase = PR_FALSE; | |
90 | |
91 rv = cert_FindExtension(cert->extensions, tag, &urlitem); | |
92 if ( rv == SECSuccess ) { | |
93 rv = cert_FindExtension(cert->extensions, SEC_OID_NS_CERT_EXT_BASE_URL, | |
94 &baseitem); | |
95 if ( rv == SECSuccess ) { | |
96 hasbase = PR_TRUE; | |
97 } | |
98 | |
99 } else if ( catag ) { | |
100 /* if the cert doesn't have the extensions, see if the issuer does */ | |
101 rv = CERT_FindIssuerCertExtension(cert, catag, &urlitem); | |
102 if ( rv != SECSuccess ) { | |
103 goto loser; | |
104 } | |
105 rv = CERT_FindIssuerCertExtension(cert, SEC_OID_NS_CERT_EXT_BASE_URL, | |
106 &baseitem); | |
107 if ( rv == SECSuccess ) { | |
108 hasbase = PR_TRUE; | |
109 } | |
110 } else { | |
111 goto loser; | |
112 } | |
113 | |
114 rv = SEC_QuickDERDecodeItem(arena, &urlstringitem, | |
115 SEC_ASN1_GET(SEC_IA5StringTemplate), &urlitem); | |
116 | |
117 if ( rv != SECSuccess ) { | |
118 goto loser; | |
119 } | |
120 if ( hasbase ) { | |
121 rv = SEC_QuickDERDecodeItem(arena, &basestringitem, | |
122 SEC_ASN1_GET(SEC_IA5StringTemplate), | |
123 &baseitem); | |
124 | |
125 if ( rv != SECSuccess ) { | |
126 goto loser; | |
127 } | |
128 } | |
129 | |
130 len = urlstringitem.len + ( hasbase ? basestringitem.len : 0 ) + 1; | |
131 | |
132 str = urlstring = (char *)PORT_Alloc(len); | |
133 if ( urlstring == NULL ) { | |
134 goto loser; | |
135 } | |
136 | |
137 /* copy the URL base first */ | |
138 if ( hasbase ) { | |
139 | |
140 /* if the urlstring has a : in it, then we assume it is an absolute | |
141 * URL, and will not get the base string pre-pended | |
142 */ | |
143 for ( i = 0; i < urlstringitem.len; i++ ) { | |
144 if ( urlstringitem.data[i] == ':' ) { | |
145 goto nobase; | |
146 } | |
147 } | |
148 | |
149 PORT_Memcpy(str, basestringitem.data, basestringitem.len); | |
150 str += basestringitem.len; | |
151 | |
152 } | |
153 | |
154 nobase: | |
155 /* copy the rest (or all) of the URL */ | |
156 PORT_Memcpy(str, urlstringitem.data, urlstringitem.len); | |
157 str += urlstringitem.len; | |
158 | |
159 *str = '\0'; | |
160 goto done; | |
161 | |
162 loser: | |
163 if ( urlstring ) { | |
164 PORT_Free(urlstring); | |
165 } | |
166 | |
167 urlstring = NULL; | |
168 done: | |
169 if ( arena ) { | |
170 PORT_FreeArena(arena, PR_FALSE); | |
171 } | |
172 if ( baseitem.data ) { | |
173 PORT_Free(baseitem.data); | |
174 } | |
175 if ( urlitem.data ) { | |
176 PORT_Free(urlitem.data); | |
177 } | |
178 | |
179 return(urlstring); | |
180 } | |
181 | |
182 /* | 46 /* |
183 * get the value of the Netscape Certificate Type Extension | 47 * get the value of the Netscape Certificate Type Extension |
184 */ | 48 */ |
185 SECStatus | 49 SECStatus |
186 CERT_FindNSCertTypeExtension(CERTCertificate *cert, SECItem *retItem) | 50 CERT_FindNSCertTypeExtension(CERTCertificate *cert, SECItem *retItem) |
187 { | 51 { |
188 | 52 |
189 return (CERT_FindBitStringExtension | 53 return (CERT_FindBitStringExtension |
190 (cert->extensions, SEC_OID_NS_CERT_EXT_CERT_TYPE, retItem)); | 54 (cert->extensions, SEC_OID_NS_CERT_EXT_CERT_TYPE, retItem)); |
191 } | 55 } |
(...skipping 164 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
356 if (rv == SECFailure) { | 220 if (rv == SECFailure) { |
357 rv = (PORT_GetError () == SEC_ERROR_EXTENSION_NOT_FOUND) ? | 221 rv = (PORT_GetError () == SEC_ERROR_EXTENSION_NOT_FOUND) ? |
358 SECSuccess : SECFailure; | 222 SECSuccess : SECFailure; |
359 } else if (!(keyUsage.data[0] & usage)) { | 223 } else if (!(keyUsage.data[0] & usage)) { |
360 PORT_SetError (SEC_ERROR_CERT_USAGES_INVALID); | 224 PORT_SetError (SEC_ERROR_CERT_USAGES_INVALID); |
361 rv = SECFailure; | 225 rv = SECFailure; |
362 } | 226 } |
363 PORT_Free (keyUsage.data); | 227 PORT_Free (keyUsage.data); |
364 return (rv); | 228 return (rv); |
365 } | 229 } |
OLD | NEW |