File: | libxmlsec/unxlngi6.pro/misc/build/xmlsec1-1.2.14/src/nss/x509vfy.c |
Location: | line 230, column 25 |
Description: | Access to field 'subjectName' results in a dereference of a null pointer (loaded from variable 'cert') |
1 | /** | |||
2 | * XMLSec library | |||
3 | * | |||
4 | * X509 support | |||
5 | * | |||
6 | * | |||
7 | * This is free software; see Copyright file in the source | |||
8 | * distribution for preciese wording. | |||
9 | * | |||
10 | * Copyright (c) 2003 America Online, Inc. All rights reserved. | |||
11 | */ | |||
12 | #include "globals.h" | |||
13 | ||||
14 | #ifndef XMLSEC_NO_X509 | |||
15 | ||||
16 | #include <stdlib.h> | |||
17 | #include <stdio.h> | |||
18 | #include <string.h> | |||
19 | #include <ctype.h> | |||
20 | #include <errno(*__errno_location ()).h> | |||
21 | ||||
22 | #include <cert.h> | |||
23 | #include <secerr.h> | |||
24 | ||||
25 | #include <libxml/tree.h> | |||
26 | ||||
27 | #include <xmlsec/xmlsec.h> | |||
28 | #include <xmlsec/xmltree.h> | |||
29 | #include <xmlsec/keys.h> | |||
30 | #include <xmlsec/keyinfo.h> | |||
31 | #include <xmlsec/keysmngr.h> | |||
32 | #include <xmlsec/base64.h> | |||
33 | #include <xmlsec/bn.h> | |||
34 | #include <xmlsec/errors.h> | |||
35 | ||||
36 | #include <xmlsec/nss/crypto.h> | |||
37 | #include <xmlsec/nss/x509.h> | |||
38 | ||||
39 | /************************************************************************** | |||
40 | * | |||
41 | * Internal NSS X509 store CTX | |||
42 | * | |||
43 | *************************************************************************/ | |||
44 | typedef struct _xmlSecNssX509StoreCtx xmlSecNssX509StoreCtx, | |||
45 | *xmlSecNssX509StoreCtxPtr; | |||
46 | struct _xmlSecNssX509StoreCtx { | |||
47 | CERTCertList* certsList; /* just keeping a reference to destroy later */ | |||
48 | }; | |||
49 | ||||
50 | /**************************************************************************** | |||
51 | * | |||
52 | * xmlSecNssKeyDataStoreX509Id: | |||
53 | * | |||
54 | * xmlSecNssX509StoreCtx is located after xmlSecTransform | |||
55 | * | |||
56 | ***************************************************************************/ | |||
57 | #define xmlSecNssX509StoreGetCtx(store)((xmlSecNssX509StoreCtxPtr)(((unsigned char*)(store)) + sizeof (xmlSecKeyDataStoreKlass))) \ | |||
58 | ((xmlSecNssX509StoreCtxPtr)(((xmlSecByteunsigned char*)(store)) + \ | |||
59 | sizeof(xmlSecKeyDataStoreKlass))) | |||
60 | #define xmlSecNssX509StoreSize(sizeof(xmlSecKeyDataStoreKlass) + sizeof(xmlSecNssX509StoreCtx )) \ | |||
61 | (sizeof(xmlSecKeyDataStoreKlass) + sizeof(xmlSecNssX509StoreCtx)) | |||
62 | ||||
63 | static int xmlSecNssX509StoreInitialize (xmlSecKeyDataStorePtr store); | |||
64 | static void xmlSecNssX509StoreFinalize (xmlSecKeyDataStorePtr store); | |||
65 | static int xmlSecNssIntegerToItem( const xmlChar* integer , SECItem *it ) ; | |||
66 | ||||
67 | static xmlSecKeyDataStoreKlass xmlSecNssX509StoreKlass = { | |||
68 | sizeof(xmlSecKeyDataStoreKlass), | |||
69 | xmlSecNssX509StoreSize(sizeof(xmlSecKeyDataStoreKlass) + sizeof(xmlSecNssX509StoreCtx )), | |||
70 | ||||
71 | /* data */ | |||
72 | xmlSecNameX509Store, /* const xmlChar* name; */ | |||
73 | ||||
74 | /* constructors/destructor */ | |||
75 | xmlSecNssX509StoreInitialize, /* xmlSecKeyDataStoreInitializeMethod initialize; */ | |||
76 | xmlSecNssX509StoreFinalize, /* xmlSecKeyDataStoreFinalizeMethod finalize; */ | |||
77 | ||||
78 | /* reserved for the future */ | |||
79 | NULL((void*)0), /* void* reserved0; */ | |||
80 | NULL((void*)0), /* void* reserved1; */ | |||
81 | }; | |||
82 | ||||
83 | static CERTCertificate* xmlSecNssX509FindCert(xmlChar *subjectName, | |||
84 | xmlChar *issuerName, | |||
85 | xmlChar *issuerSerial, | |||
86 | xmlChar *ski); | |||
87 | ||||
88 | ||||
89 | /** | |||
90 | * xmlSecNssX509StoreGetKlass: | |||
91 | * | |||
92 | * The NSS X509 certificates key data store klass. | |||
93 | * | |||
94 | * Returns: pointer to NSS X509 certificates key data store klass. | |||
95 | */ | |||
96 | xmlSecKeyDataStoreId | |||
97 | xmlSecNssX509StoreGetKlass(void) { | |||
98 | return(&xmlSecNssX509StoreKlass); | |||
99 | } | |||
100 | ||||
101 | /** | |||
102 | * xmlSecNssX509StoreFindCert: | |||
103 | * @store: the pointer to X509 key data store klass. | |||
104 | * @subjectName: the desired certificate name. | |||
105 | * @issuerName: the desired certificate issuer name. | |||
106 | * @issuerSerial: the desired certificate issuer serial number. | |||
107 | * @ski: the desired certificate SKI. | |||
108 | * @keyInfoCtx: the pointer to <dsig:KeyInfo/> element processing context. | |||
109 | * | |||
110 | * Searches @store for a certificate that matches given criteria. | |||
111 | * | |||
112 | * Returns: pointer to found certificate or NULL if certificate is not found | |||
113 | * or an error occurs. | |||
114 | */ | |||
115 | CERTCertificate * | |||
116 | xmlSecNssX509StoreFindCert(xmlSecKeyDataStorePtr store, xmlChar *subjectName, | |||
117 | xmlChar *issuerName, xmlChar *issuerSerial, | |||
118 | xmlChar *ski, xmlSecKeyInfoCtx* keyInfoCtx) { | |||
119 | xmlSecNssX509StoreCtxPtr ctx; | |||
120 | ||||
121 | xmlSecAssert2(xmlSecKeyDataStoreCheckId(store, xmlSecNssX509StoreId), NULL)if(!( (((( ( store ) ) != ((void*)0)) && ((( ( store ) )->id) != ((void*)0))) && ((( store )->id) == ( xmlSecNssX509StoreGetKlass() ))) ) ) { xmlSecError("x509vfy.c" ,121,__FUNCTION__, ((void*)0), "xmlSecKeyDataStoreCheckId(store, xmlSecNssX509StoreId)" , 100, " "); return(((void*)0)); }; | |||
122 | xmlSecAssert2(keyInfoCtx != NULL, NULL)if(!( keyInfoCtx != ((void*)0) ) ) { xmlSecError("x509vfy.c", 122,__FUNCTION__, ((void*)0), "keyInfoCtx != NULL", 100, " ") ; return(((void*)0)); }; | |||
123 | ||||
124 | ctx = xmlSecNssX509StoreGetCtx(store)((xmlSecNssX509StoreCtxPtr)(((unsigned char*)(store)) + sizeof (xmlSecKeyDataStoreKlass))); | |||
125 | xmlSecAssert2(ctx != NULL, NULL)if(!( ctx != ((void*)0) ) ) { xmlSecError("x509vfy.c",125,__FUNCTION__ , ((void*)0), "ctx != NULL", 100, " "); return(((void*)0)); }; | |||
126 | ||||
127 | return(xmlSecNssX509FindCert(subjectName, issuerName, issuerSerial, ski)); | |||
128 | } | |||
129 | ||||
130 | /** | |||
131 | * xmlSecNssX509StoreVerify: | |||
132 | * @store: the pointer to X509 key data store klass. | |||
133 | * @certs: the untrusted certificates stack. | |||
134 | * @keyInfoCtx: the pointer to <dsig:KeyInfo/> element processing context. | |||
135 | * | |||
136 | * Verifies @certs list. | |||
137 | * | |||
138 | * Returns: pointer to the first verified certificate from @certs. | |||
139 | */ | |||
140 | CERTCertificate * | |||
141 | xmlSecNssX509StoreVerify(xmlSecKeyDataStorePtr store, CERTCertList* certs, | |||
142 | xmlSecKeyInfoCtx* keyInfoCtx) { | |||
143 | xmlSecNssX509StoreCtxPtr ctx; | |||
144 | CERTCertListNode* head; | |||
145 | CERTCertificate* cert = NULL((void*)0); | |||
146 | CERTCertListNode* head1; | |||
147 | CERTCertificate* cert1 = NULL((void*)0); | |||
148 | SECStatus status = SECFailure; | |||
149 | int64 timeboundary; | |||
150 | int64 tmp1, tmp2; | |||
151 | ||||
152 | xmlSecAssert2(xmlSecKeyDataStoreCheckId(store, xmlSecNssX509StoreId), NULL)if(!( (((( ( store ) ) != ((void*)0)) && ((( ( store ) )->id) != ((void*)0))) && ((( store )->id) == ( xmlSecNssX509StoreGetKlass() ))) ) ) { xmlSecError("x509vfy.c" ,152,__FUNCTION__, ((void*)0), "xmlSecKeyDataStoreCheckId(store, xmlSecNssX509StoreId)" , 100, " "); return(((void*)0)); }; | |||
153 | xmlSecAssert2(certs != NULL, NULL)if(!( certs != ((void*)0) ) ) { xmlSecError("x509vfy.c",153,__FUNCTION__ , ((void*)0), "certs != NULL", 100, " "); return(((void*)0)); }; | |||
154 | xmlSecAssert2(keyInfoCtx != NULL, NULL)if(!( keyInfoCtx != ((void*)0) ) ) { xmlSecError("x509vfy.c", 154,__FUNCTION__, ((void*)0), "keyInfoCtx != NULL", 100, " ") ; return(((void*)0)); }; | |||
155 | ||||
156 | ctx = xmlSecNssX509StoreGetCtx(store)((xmlSecNssX509StoreCtxPtr)(((unsigned char*)(store)) + sizeof (xmlSecKeyDataStoreKlass))); | |||
157 | xmlSecAssert2(ctx != NULL, NULL)if(!( ctx != ((void*)0) ) ) { xmlSecError("x509vfy.c",157,__FUNCTION__ , ((void*)0), "ctx != NULL", 100, " "); return(((void*)0)); }; | |||
158 | ||||
159 | for (head = CERT_LIST_HEAD(certs)((CERTCertListNode *)(&certs->list)->next); | |||
| ||||
160 | !CERT_LIST_END(head, certs)(((void *)head) == ((void *)&certs->list)); | |||
161 | head = CERT_LIST_NEXT(head)((CERTCertListNode *)head->links.next)) { | |||
162 | cert = head->cert; | |||
163 | if(keyInfoCtx->certsVerificationTime > 0) { | |||
164 | /* convert the time since epoch in seconds to microseconds */ | |||
165 | LL_UI2L(timeboundary, keyInfoCtx->certsVerificationTime)((timeboundary) = (PRInt64)(keyInfoCtx->certsVerificationTime )); | |||
166 | tmp1 = (int64)PR_USEC_PER_SEC1000000L; | |||
167 | tmp2 = timeboundary; | |||
168 | LL_MUL(timeboundary, tmp1, tmp2)((timeboundary) = (tmp1) * (tmp2)); | |||
169 | } else { | |||
170 | timeboundary = PR_Now(); | |||
171 | } | |||
172 | ||||
173 | /* if cert is the issuer of any other cert in the list, then it is | |||
174 | * to be skipped */ | |||
175 | for (head1 = CERT_LIST_HEAD(certs)((CERTCertListNode *)(&certs->list)->next); | |||
176 | !CERT_LIST_END(head1, certs)(((void *)head1) == ((void *)&certs->list)); | |||
177 | head1 = CERT_LIST_NEXT(head1)((CERTCertListNode *)head1->links.next)) { | |||
178 | ||||
179 | cert1 = head1->cert; | |||
180 | if (cert1 == cert) { | |||
181 | continue; | |||
182 | } | |||
183 | ||||
184 | if (SECITEM_CompareItem(&cert1->derIssuer, &cert->derSubject) | |||
185 | == SECEqual) { | |||
186 | break; | |||
187 | } | |||
188 | } | |||
189 | ||||
190 | if (!CERT_LIST_END(head1, certs)(((void *)head1) == ((void *)&certs->list))) { | |||
191 | continue; | |||
192 | } | |||
193 | ||||
194 | ||||
195 | /* | |||
196 | JL: OpenOffice.org implements its own certificate verification routine. | |||
197 | The goal is to seperate validation of the signature | |||
198 | and the certificate. For example, OOo could show that the document signature is valid, | |||
199 | but the certificate could not be verified. If we do not prevent the verification of | |||
200 | the certificate by libxmlsec and the verification fails, then the XML signature may not be | |||
201 | verified. This would happen, for example, if the root certificate is not installed. | |||
202 | ||||
203 | status = CERT_VerifyCertificate(CERT_GetDefaultCertDB(), | |||
204 | cert, PR_FALSE, | |||
205 | (SECCertificateUsage)0, | |||
206 | timeboundary , NULL, NULL, NULL); | |||
207 | if (status == SECSuccess) { | |||
208 | break; | |||
209 | } | |||
210 | ||||
211 | */ | |||
212 | status = SECSuccess; | |||
213 | break; | |||
214 | ||||
215 | } | |||
216 | ||||
217 | if (status == SECSuccess) { | |||
218 | return (cert); | |||
219 | } | |||
220 | ||||
221 | switch(PORT_GetError()) { | |||
222 | case SEC_ERROR_EXPIRED_ISSUER_CERTIFICATE: | |||
223 | case SEC_ERROR_CA_CERT_INVALID: | |||
224 | case SEC_ERROR_UNKNOWN_SIGNER: | |||
225 | xmlSecError(XMLSEC_ERRORS_HERE"x509vfy.c",225,__FUNCTION__, | |||
226 | xmlSecErrorsSafeString(xmlSecKeyDataStoreGetName(store))(((((((( (store) ) != ((void*)0)) && ((( (store) )-> id) != ((void*)0)))) ? ((((store)->id)) ? (((store)->id )->name) : ((void*)0)) : ((void*)0))) != ((void*)0)) ? ((char *)(((((( (store) ) != ((void*)0)) && ((( (store) )-> id) != ((void*)0)))) ? ((((store)->id)) ? (((store)->id )->name) : ((void*)0)) : ((void*)0)))) : (char*)"NULL"), | |||
227 | NULL((void*)0), | |||
228 | XMLSEC_ERRORS_R_CERT_ISSUER_FAILED74, | |||
229 | "cert with subject name %s could not be verified because the issuer's cert is expired/invalid or not found", | |||
230 | cert->subjectName); | |||
| ||||
231 | break; | |||
232 | case SEC_ERROR_EXPIRED_CERTIFICATE: | |||
233 | xmlSecError(XMLSEC_ERRORS_HERE"x509vfy.c",233,__FUNCTION__, | |||
234 | xmlSecErrorsSafeString(xmlSecKeyDataStoreGetName(store))(((((((( (store) ) != ((void*)0)) && ((( (store) )-> id) != ((void*)0)))) ? ((((store)->id)) ? (((store)->id )->name) : ((void*)0)) : ((void*)0))) != ((void*)0)) ? ((char *)(((((( (store) ) != ((void*)0)) && ((( (store) )-> id) != ((void*)0)))) ? ((((store)->id)) ? (((store)->id )->name) : ((void*)0)) : ((void*)0)))) : (char*)"NULL"), | |||
235 | NULL((void*)0), | |||
236 | XMLSEC_ERRORS_R_CERT_HAS_EXPIRED76, | |||
237 | "cert with subject name %s has expired", | |||
238 | cert->subjectName); | |||
239 | break; | |||
240 | case SEC_ERROR_REVOKED_CERTIFICATE: | |||
241 | xmlSecError(XMLSEC_ERRORS_HERE"x509vfy.c",241,__FUNCTION__, | |||
242 | xmlSecErrorsSafeString(xmlSecKeyDataStoreGetName(store))(((((((( (store) ) != ((void*)0)) && ((( (store) )-> id) != ((void*)0)))) ? ((((store)->id)) ? (((store)->id )->name) : ((void*)0)) : ((void*)0))) != ((void*)0)) ? ((char *)(((((( (store) ) != ((void*)0)) && ((( (store) )-> id) != ((void*)0)))) ? ((((store)->id)) ? (((store)->id )->name) : ((void*)0)) : ((void*)0)))) : (char*)"NULL"), | |||
243 | NULL((void*)0), | |||
244 | XMLSEC_ERRORS_R_CERT_REVOKED73, | |||
245 | "cert with subject name %s has been revoked", | |||
246 | cert->subjectName); | |||
247 | break; | |||
248 | default: | |||
249 | xmlSecError(XMLSEC_ERRORS_HERE"x509vfy.c",249,__FUNCTION__, | |||
250 | xmlSecErrorsSafeString(xmlSecKeyDataStoreGetName(store))(((((((( (store) ) != ((void*)0)) && ((( (store) )-> id) != ((void*)0)))) ? ((((store)->id)) ? (((store)->id )->name) : ((void*)0)) : ((void*)0))) != ((void*)0)) ? ((char *)(((((( (store) ) != ((void*)0)) && ((( (store) )-> id) != ((void*)0)))) ? ((((store)->id)) ? (((store)->id )->name) : ((void*)0)) : ((void*)0)))) : (char*)"NULL"), | |||
251 | NULL((void*)0), | |||
252 | XMLSEC_ERRORS_R_CERT_VERIFY_FAILED71, | |||
253 | "cert with subject name %s could not be verified, errcode %d", | |||
254 | cert->subjectName, | |||
255 | PORT_GetError()); | |||
256 | break; | |||
257 | } | |||
258 | ||||
259 | return (NULL((void*)0)); | |||
260 | } | |||
261 | ||||
262 | /** | |||
263 | * xmlSecNssX509StoreAdoptCert: | |||
264 | * @store: the pointer to X509 key data store klass. | |||
265 | * @cert: the pointer to NSS X509 certificate. | |||
266 | * @type: the certificate type (trusted/untrusted). | |||
267 | * | |||
268 | * Adds trusted (root) or untrusted certificate to the store. | |||
269 | * | |||
270 | * Returns: 0 on success or a negative value if an error occurs. | |||
271 | */ | |||
272 | int | |||
273 | xmlSecNssX509StoreAdoptCert(xmlSecKeyDataStorePtr store, CERTCertificate* cert, xmlSecKeyDataType type ATTRIBUTE_UNUSED__attribute__((unused))) { | |||
274 | xmlSecNssX509StoreCtxPtr ctx; | |||
275 | int ret; | |||
276 | ||||
277 | xmlSecAssert2(xmlSecKeyDataStoreCheckId(store, xmlSecNssX509StoreId), -1)if(!( (((( ( store ) ) != ((void*)0)) && ((( ( store ) )->id) != ((void*)0))) && ((( store )->id) == ( xmlSecNssX509StoreGetKlass() ))) ) ) { xmlSecError("x509vfy.c" ,277,__FUNCTION__, ((void*)0), "xmlSecKeyDataStoreCheckId(store, xmlSecNssX509StoreId)" , 100, " "); return(-1); }; | |||
278 | xmlSecAssert2(cert != NULL, -1)if(!( cert != ((void*)0) ) ) { xmlSecError("x509vfy.c",278,__FUNCTION__ , ((void*)0), "cert != NULL", 100, " "); return(-1); }; | |||
279 | ||||
280 | ctx = xmlSecNssX509StoreGetCtx(store)((xmlSecNssX509StoreCtxPtr)(((unsigned char*)(store)) + sizeof (xmlSecKeyDataStoreKlass))); | |||
281 | xmlSecAssert2(ctx != NULL, -1)if(!( ctx != ((void*)0) ) ) { xmlSecError("x509vfy.c",281,__FUNCTION__ , ((void*)0), "ctx != NULL", 100, " "); return(-1); }; | |||
282 | ||||
283 | if(ctx->certsList == NULL((void*)0)) { | |||
284 | ctx->certsList = CERT_NewCertList(); | |||
285 | if(ctx->certsList == NULL((void*)0)) { | |||
286 | xmlSecError(XMLSEC_ERRORS_HERE"x509vfy.c",286,__FUNCTION__, | |||
287 | xmlSecErrorsSafeString(xmlSecKeyDataStoreGetName(store))(((((((( (store) ) != ((void*)0)) && ((( (store) )-> id) != ((void*)0)))) ? ((((store)->id)) ? (((store)->id )->name) : ((void*)0)) : ((void*)0))) != ((void*)0)) ? ((char *)(((((( (store) ) != ((void*)0)) && ((( (store) )-> id) != ((void*)0)))) ? ((((store)->id)) ? (((store)->id )->name) : ((void*)0)) : ((void*)0)))) : (char*)"NULL"), | |||
288 | "CERT_NewCertList", | |||
289 | XMLSEC_ERRORS_R_CRYPTO_FAILED4, | |||
290 | "error code=%d", PORT_GetError()); | |||
291 | return(-1); | |||
292 | } | |||
293 | } | |||
294 | ||||
295 | ret = CERT_AddCertToListTail(ctx->certsList, cert); | |||
296 | if(ret != SECSuccess) { | |||
297 | xmlSecError(XMLSEC_ERRORS_HERE"x509vfy.c",297,__FUNCTION__, | |||
298 | xmlSecErrorsSafeString(xmlSecKeyDataStoreGetName(store))(((((((( (store) ) != ((void*)0)) && ((( (store) )-> id) != ((void*)0)))) ? ((((store)->id)) ? (((store)->id )->name) : ((void*)0)) : ((void*)0))) != ((void*)0)) ? ((char *)(((((( (store) ) != ((void*)0)) && ((( (store) )-> id) != ((void*)0)))) ? ((((store)->id)) ? (((store)->id )->name) : ((void*)0)) : ((void*)0)))) : (char*)"NULL"), | |||
299 | "CERT_AddCertToListTail", | |||
300 | XMLSEC_ERRORS_R_CRYPTO_FAILED4, | |||
301 | "error code=%d", PORT_GetError()); | |||
302 | return(-1); | |||
303 | } | |||
304 | ||||
305 | return(0); | |||
306 | } | |||
307 | ||||
308 | static int | |||
309 | xmlSecNssX509StoreInitialize(xmlSecKeyDataStorePtr store) { | |||
310 | xmlSecNssX509StoreCtxPtr ctx; | |||
311 | xmlSecAssert2(xmlSecKeyDataStoreCheckId(store, xmlSecNssX509StoreId), -1)if(!( (((( ( store ) ) != ((void*)0)) && ((( ( store ) )->id) != ((void*)0))) && ((( store )->id) == ( xmlSecNssX509StoreGetKlass() ))) ) ) { xmlSecError("x509vfy.c" ,311,__FUNCTION__, ((void*)0), "xmlSecKeyDataStoreCheckId(store, xmlSecNssX509StoreId)" , 100, " "); return(-1); }; | |||
312 | ||||
313 | ctx = xmlSecNssX509StoreGetCtx(store)((xmlSecNssX509StoreCtxPtr)(((unsigned char*)(store)) + sizeof (xmlSecKeyDataStoreKlass))); | |||
314 | xmlSecAssert2(ctx != NULL, -1)if(!( ctx != ((void*)0) ) ) { xmlSecError("x509vfy.c",314,__FUNCTION__ , ((void*)0), "ctx != NULL", 100, " "); return(-1); }; | |||
315 | ||||
316 | memset(ctx, 0, sizeof(xmlSecNssX509StoreCtx)); | |||
317 | ||||
318 | return(0); | |||
319 | } | |||
320 | ||||
321 | static void | |||
322 | xmlSecNssX509StoreFinalize(xmlSecKeyDataStorePtr store) { | |||
323 | xmlSecNssX509StoreCtxPtr ctx; | |||
324 | xmlSecAssert(xmlSecKeyDataStoreCheckId(store, xmlSecNssX509StoreId))if(!( (((( ( store ) ) != ((void*)0)) && ((( ( store ) )->id) != ((void*)0))) && ((( store )->id) == ( xmlSecNssX509StoreGetKlass() ))) ) ) { xmlSecError("x509vfy.c" ,324,__FUNCTION__, ((void*)0), "xmlSecKeyDataStoreCheckId(store, xmlSecNssX509StoreId)" , 100, " "); return; }; | |||
325 | ||||
326 | ctx = xmlSecNssX509StoreGetCtx(store)((xmlSecNssX509StoreCtxPtr)(((unsigned char*)(store)) + sizeof (xmlSecKeyDataStoreKlass))); | |||
327 | xmlSecAssert(ctx != NULL)if(!( ctx != ((void*)0) ) ) { xmlSecError("x509vfy.c",327,__FUNCTION__ , ((void*)0), "ctx != NULL", 100, " "); return; }; | |||
328 | ||||
329 | if (ctx->certsList) { | |||
330 | CERT_DestroyCertList(ctx->certsList); | |||
331 | ctx->certsList = NULL((void*)0); | |||
332 | } | |||
333 | ||||
334 | memset(ctx, 0, sizeof(xmlSecNssX509StoreCtx)); | |||
335 | } | |||
336 | ||||
337 | ||||
338 | /***************************************************************************** | |||
339 | * | |||
340 | * Low-level x509 functions | |||
341 | * | |||
342 | *****************************************************************************/ | |||
343 | static CERTCertificate* | |||
344 | xmlSecNssX509FindCert(xmlChar *subjectName, xmlChar *issuerName, | |||
345 | xmlChar *issuerSerial, xmlChar *ski) { | |||
346 | CERTCertificate *cert = NULL((void*)0); | |||
347 | CERTName *name = NULL((void*)0); | |||
348 | SECItem *nameitem = NULL((void*)0); | |||
349 | PRArenaPoolPLArenaPool *arena = NULL((void*)0); | |||
350 | ||||
351 | if (subjectName != NULL((void*)0)) { | |||
352 | arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE(2048)); | |||
353 | if (arena == NULL((void*)0)) { | |||
354 | xmlSecError(XMLSEC_ERRORS_HERE"x509vfy.c",354,__FUNCTION__, | |||
355 | NULL((void*)0), | |||
356 | "PORT_NewArena", | |||
357 | XMLSEC_ERRORS_R_CRYPTO_FAILED4, | |||
358 | "error code=%d", PORT_GetError()); | |||
359 | goto done; | |||
360 | } | |||
361 | ||||
362 | name = CERT_AsciiToName((char*)subjectName); | |||
363 | if (name == NULL((void*)0)) { | |||
364 | xmlSecError(XMLSEC_ERRORS_HERE"x509vfy.c",364,__FUNCTION__, | |||
365 | NULL((void*)0), | |||
366 | "CERT_AsciiToName", | |||
367 | XMLSEC_ERRORS_R_XMLSEC_FAILED1, | |||
368 | "error code=%d", PORT_GetError()); | |||
369 | goto done; | |||
370 | } | |||
371 | ||||
372 | nameitem = SEC_ASN1EncodeItem(arena, NULL((void*)0), (void *)name, | |||
373 | SEC_ASN1_GET(CERT_NameTemplate)CERT_NameTemplate); | |||
374 | if (nameitem == NULL((void*)0)) { | |||
375 | xmlSecError(XMLSEC_ERRORS_HERE"x509vfy.c",375,__FUNCTION__, | |||
376 | NULL((void*)0), | |||
377 | "SEC_ASN1EncodeItem", | |||
378 | XMLSEC_ERRORS_R_XMLSEC_FAILED1, | |||
379 | "error code=%d", PORT_GetError()); | |||
380 | goto done; | |||
381 | } | |||
382 | ||||
383 | cert = CERT_FindCertByName(CERT_GetDefaultCertDB(), nameitem); | |||
384 | goto done; | |||
385 | } | |||
386 | ||||
387 | if((issuerName != NULL((void*)0)) && (issuerSerial != NULL((void*)0))) { | |||
388 | CERTIssuerAndSN issuerAndSN; | |||
389 | ||||
390 | arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE(2048)); | |||
391 | if (arena == NULL((void*)0)) { | |||
392 | xmlSecError(XMLSEC_ERRORS_HERE"x509vfy.c",392,__FUNCTION__, | |||
393 | NULL((void*)0), | |||
394 | "PORT_NewArena", | |||
395 | XMLSEC_ERRORS_R_CRYPTO_FAILED4, | |||
396 | "error code=%d", PORT_GetError()); | |||
397 | goto done; | |||
398 | } | |||
399 | ||||
400 | name = CERT_AsciiToName((char*)issuerName); | |||
401 | if (name == NULL((void*)0)) { | |||
402 | xmlSecError(XMLSEC_ERRORS_HERE"x509vfy.c",402,__FUNCTION__, | |||
403 | NULL((void*)0), | |||
404 | "CERT_AsciiToName", | |||
405 | XMLSEC_ERRORS_R_XMLSEC_FAILED1, | |||
406 | "error code=%d", PORT_GetError()); | |||
407 | goto done; | |||
408 | } | |||
409 | ||||
410 | nameitem = SEC_ASN1EncodeItem(arena, NULL((void*)0), (void *)name, | |||
411 | SEC_ASN1_GET(CERT_NameTemplate)CERT_NameTemplate); | |||
412 | if (nameitem == NULL((void*)0)) { | |||
413 | xmlSecError(XMLSEC_ERRORS_HERE"x509vfy.c",413,__FUNCTION__, | |||
414 | NULL((void*)0), | |||
415 | "SEC_ASN1EncodeItem", | |||
416 | XMLSEC_ERRORS_R_XMLSEC_FAILED1, | |||
417 | "error code=%d", PORT_GetError()); | |||
418 | goto done; | |||
419 | } | |||
420 | ||||
421 | memset(&issuerAndSN, 0, sizeof(issuerAndSN)); | |||
422 | ||||
423 | issuerAndSN.derIssuer.data = nameitem->data; | |||
424 | issuerAndSN.derIssuer.len = nameitem->len; | |||
425 | ||||
426 | if( xmlSecNssIntegerToItem( issuerSerial, &issuerAndSN.serialNumber ) < 0 ) { | |||
427 | xmlSecError(XMLSEC_ERRORS_HERE"x509vfy.c",427,__FUNCTION__, | |||
428 | NULL((void*)0), | |||
429 | "xmlSecNssIntegerToItem", | |||
430 | XMLSEC_ERRORS_R_XMLSEC_FAILED1, | |||
431 | "serial number=%s", | |||
432 | xmlSecErrorsSafeString(issuerSerial)(((issuerSerial) != ((void*)0)) ? ((char*)(issuerSerial)) : ( char*)"NULL")); | |||
433 | goto done; | |||
434 | } | |||
435 | ||||
436 | cert = CERT_FindCertByIssuerAndSN(CERT_GetDefaultCertDB(), | |||
437 | &issuerAndSN); | |||
438 | SECITEM_FreeItem(&issuerAndSN.serialNumber, PR_FALSE0); | |||
439 | goto done; | |||
440 | } | |||
441 | ||||
442 | if(ski != NULL((void*)0)) { | |||
443 | SECItem subjKeyID; | |||
444 | int len; | |||
445 | ||||
446 | len = xmlSecBase64Decode(ski, (xmlSecByteunsigned char*)ski, xmlStrlen(ski)); | |||
447 | if(len < 0) { | |||
448 | xmlSecError(XMLSEC_ERRORS_HERE"x509vfy.c",448,__FUNCTION__, | |||
449 | NULL((void*)0), | |||
450 | "xmlSecBase64Decode", | |||
451 | XMLSEC_ERRORS_R_XMLSEC_FAILED1, | |||
452 | "ski=%s", | |||
453 | xmlSecErrorsSafeString(ski)(((ski) != ((void*)0)) ? ((char*)(ski)) : (char*)"NULL")); | |||
454 | goto done; | |||
455 | } | |||
456 | ||||
457 | memset(&subjKeyID, 0, sizeof(subjKeyID)); | |||
458 | subjKeyID.data = ski; | |||
459 | subjKeyID.len = xmlStrlen(ski); | |||
460 | cert = CERT_FindCertBySubjectKeyID(CERT_GetDefaultCertDB(), | |||
461 | &subjKeyID); | |||
462 | } | |||
463 | ||||
464 | done: | |||
465 | if (arena != NULL((void*)0)) { | |||
466 | PORT_FreeArena(arena, PR_FALSE0); | |||
467 | } | |||
468 | if (name != NULL((void*)0)) { | |||
469 | CERT_DestroyName(name); | |||
470 | } | |||
471 | ||||
472 | return(cert); | |||
473 | } | |||
474 | ||||
475 | /* code lifted from NSS */ | |||
476 | static void | |||
477 | xmlSecNssNumToItem(SECItem *it, unsigned long ui) | |||
478 | { | |||
479 | unsigned char bb[5]; | |||
480 | int len; | |||
481 | ||||
482 | bb[0] = 0; | |||
483 | bb[1] = (unsigned char) (ui >> 24); | |||
484 | bb[2] = (unsigned char) (ui >> 16); | |||
485 | bb[3] = (unsigned char) (ui >> 8); | |||
486 | bb[4] = (unsigned char) (ui); | |||
487 | ||||
488 | /* | |||
489 | ** Small integers are encoded in a single byte. Larger integers | |||
490 | ** require progressively more space. | |||
491 | */ | |||
492 | if (ui > 0x7f) { | |||
493 | if (ui > 0x7fff) { | |||
494 | if (ui > 0x7fffffL) { | |||
495 | if (ui >= 0x80000000L) { | |||
496 | len = 5; | |||
497 | } else { | |||
498 | len = 4; | |||
499 | } | |||
500 | } else { | |||
501 | len = 3; | |||
502 | } | |||
503 | } else { | |||
504 | len = 2; | |||
505 | } | |||
506 | } else { | |||
507 | len = 1; | |||
508 | } | |||
509 | ||||
510 | it->data = (unsigned char *)PORT_Alloc(len); | |||
511 | if (it->data == NULL((void*)0)) { | |||
512 | return; | |||
513 | } | |||
514 | ||||
515 | it->len = len; | |||
516 | PORT_Memcpymemcpy(it->data, bb + (sizeof(bb) - len), len); | |||
517 | } | |||
518 | ||||
519 | static int | |||
520 | xmlSecNssIntegerToItem( | |||
521 | const xmlChar* integer , | |||
522 | SECItem *item | |||
523 | ) { | |||
524 | xmlSecBn bn ; | |||
525 | xmlSecSizesize_t i, length ; | |||
526 | const xmlSecByteunsigned char* bnInteger ; | |||
527 | ||||
528 | xmlSecAssert2( integer != NULL, -1 )if(!( integer != ((void*)0) ) ) { xmlSecError("x509vfy.c",528 ,__FUNCTION__, ((void*)0), "integer != NULL", 100, " "); return (-1); } ; | |||
529 | xmlSecAssert2( item != NULL, -1 )if(!( item != ((void*)0) ) ) { xmlSecError("x509vfy.c",529,__FUNCTION__ , ((void*)0), "item != NULL", 100, " "); return(-1); } ; | |||
530 | ||||
531 | if( xmlSecBnInitialize( &bn, 0 ) < 0 ) { | |||
532 | xmlSecError(XMLSEC_ERRORS_HERE"x509vfy.c",532,__FUNCTION__, | |||
533 | NULL((void*)0), | |||
534 | "xmlSecBnInitialize", | |||
535 | XMLSEC_ERRORS_R_INVALID_DATA12, | |||
536 | XMLSEC_ERRORS_NO_MESSAGE" "); | |||
537 | return -1 ; | |||
538 | } | |||
539 | ||||
540 | if( xmlSecBnFromDecString( &bn, integer ) < 0 ) { | |||
541 | xmlSecError(XMLSEC_ERRORS_HERE"x509vfy.c",541,__FUNCTION__, | |||
542 | NULL((void*)0), | |||
543 | "xmlSecBnFromDecString", | |||
544 | XMLSEC_ERRORS_R_INVALID_DATA12, | |||
545 | XMLSEC_ERRORS_NO_MESSAGE" "); | |||
546 | xmlSecBnFinalize( &bn ) ; | |||
547 | return -1 ; | |||
548 | } | |||
549 | ||||
550 | length = xmlSecBnGetSize( &bn ) ; | |||
551 | if( length <= 0 ) { | |||
552 | xmlSecError(XMLSEC_ERRORS_HERE"x509vfy.c",552,__FUNCTION__, | |||
553 | NULL((void*)0), | |||
554 | "xmlSecBnGetSize", | |||
555 | XMLSEC_ERRORS_R_INVALID_DATA12, | |||
556 | XMLSEC_ERRORS_NO_MESSAGE" "); | |||
557 | } | |||
558 | ||||
559 | bnInteger = xmlSecBnGetData( &bn ) ; | |||
560 | if( bnInteger == NULL((void*)0) ) { | |||
561 | xmlSecError(XMLSEC_ERRORS_HERE"x509vfy.c",561,__FUNCTION__, | |||
562 | NULL((void*)0), | |||
563 | "xmlSecBnGetData", | |||
564 | XMLSEC_ERRORS_R_INVALID_DATA12, | |||
565 | XMLSEC_ERRORS_NO_MESSAGE" " ) ; | |||
566 | xmlSecBnFinalize( &bn ) ; | |||
567 | return -1 ; | |||
568 | } | |||
569 | ||||
570 | item->data = ( unsigned char * )PORT_Alloc( length ); | |||
571 | if( item->data == NULL((void*)0) ) { | |||
572 | xmlSecError(XMLSEC_ERRORS_HERE"x509vfy.c",572,__FUNCTION__, | |||
573 | NULL((void*)0), | |||
574 | "PORT_Alloc", | |||
575 | XMLSEC_ERRORS_R_INVALID_DATA12, | |||
576 | XMLSEC_ERRORS_NO_MESSAGE" " ) ; | |||
577 | xmlSecBnFinalize( &bn ) ; | |||
578 | return -1 ; | |||
579 | } | |||
580 | ||||
581 | item->len = length; | |||
582 | for( i = 0 ; i < length ; i ++ ) | |||
583 | item->data[i] = *( bnInteger + i ) ; | |||
584 | ||||
585 | xmlSecBnFinalize( &bn ) ; | |||
586 | ||||
587 | return 0 ; | |||
588 | } | |||
589 | #endif /* XMLSEC_NO_X509 */ | |||
590 | ||||
591 |