|
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) 2002-2003 Aleksey Sanin <aleksey@aleksey.com> |
|
11 * Portion Copyright © 2009 Nokia Corporation and/or its subsidiary(-ies). All rights reserved. |
|
12 */ |
|
13 #include "xmlsecc_config.h" |
|
14 #ifndef XMLSEC_NO_X509 |
|
15 #include "xmlsecc_globals.h" |
|
16 |
|
17 #include <stdlib.h> |
|
18 #include <stdio.h> |
|
19 #include <string.h> |
|
20 #include <ctype.h> |
|
21 #include <errno.h> |
|
22 |
|
23 #include <libxml2_tree.h> |
|
24 |
|
25 #include "xmlsec_xmlsec.h" |
|
26 #include "xmlsec_xmltree.h" |
|
27 #include "xmlsec_keys.h" |
|
28 #include "xmlsec_keyinfo.h" |
|
29 #include "xmlsec_keysmngr.h" |
|
30 #include "xmlsec_base64.h" |
|
31 #include "xmlsec_errors.h" |
|
32 |
|
33 #include "xmlsecc_crypto.h" |
|
34 #include "xmlsecc_x509wrapper.h" |
|
35 #include "xmlsecc_x509.h" |
|
36 #include "xmlsec_error_flag.h" |
|
37 |
|
38 #define XMLSEC_OPENSSL_097 |
|
39 |
|
40 /************************************************************************** |
|
41 * |
|
42 * Internal SymbianCrypto X509 store CTX |
|
43 * |
|
44 *************************************************************************/ |
|
45 typedef struct _xmlSecSymbianCryptoX509StoreCtx xmlSecSymbianCryptoX509StoreCtx, |
|
46 *xmlSecSymbianCryptoX509StoreCtxPtr; |
|
47 struct _xmlSecSymbianCryptoX509StoreCtx { |
|
48 X509_STORE* xst; |
|
49 STACK_OF(X509)* untrusted; |
|
50 STACK_OF(X509_CRL)* crls; |
|
51 |
|
52 #if !defined(XMLSEC_OPENSSL_096) && !defined(XMLSEC_OPENSSL_097) |
|
53 X509_VERIFY_PARAM * vpm; |
|
54 #endif /* !defined(XMLSEC_OPENSSL_096) && !defined(XMLSEC_OPENSSL_097) */ |
|
55 }; |
|
56 |
|
57 /**************************************************************************** |
|
58 * |
|
59 * xmlSecSymbianCryptoKeyDataStoreX509Id: |
|
60 * |
|
61 * xmlSecSymbianCryptoX509StoreCtx is located after xmlSecTransform |
|
62 * |
|
63 ***************************************************************************/ |
|
64 #define xmlSecSymbianCryptoX509StoreGetCtx(store) \ |
|
65 ((xmlSecSymbianCryptoX509StoreCtxPtr)(((xmlSecByte*)(store)) + \ |
|
66 sizeof(xmlSecKeyDataStoreKlass))) |
|
67 #define xmlSecSymbianCryptoX509StoreSize \ |
|
68 (sizeof(xmlSecKeyDataStoreKlass) + sizeof(xmlSecSymbianCryptoX509StoreCtx)) |
|
69 |
|
70 static int xmlSecSymbianCryptoX509StoreInitialize (xmlSecKeyDataStorePtr store); |
|
71 static void xmlSecSymbianCryptoX509StoreFinalize (xmlSecKeyDataStorePtr store); |
|
72 |
|
73 static xmlSecKeyDataStoreKlass xmlSecSymbianCryptoX509StoreKlass = { |
|
74 sizeof(xmlSecKeyDataStoreKlass), |
|
75 xmlSecSymbianCryptoX509StoreSize, |
|
76 |
|
77 /* data */ |
|
78 xmlSecNameX509Store, /* const xmlChar* name; */ |
|
79 |
|
80 /* constructors/destructor */ |
|
81 xmlSecSymbianCryptoX509StoreInitialize, /* xmlSecKeyDataStoreInitializeMethod initialize; */ |
|
82 xmlSecSymbianCryptoX509StoreFinalize, /* xmlSecKeyDataStoreFinalizeMethod finalize; */ |
|
83 |
|
84 /* reserved for the future */ |
|
85 NULL, /* void* reserved0; */ |
|
86 NULL, /* void* reserved1; */ |
|
87 }; |
|
88 |
|
89 static int xmlSecSymbianCryptoX509VerifyCrl (X509_STORE* xst, |
|
90 X509_CRL *crl ); |
|
91 static X509* xmlSecSymbianCryptoX509FindCert (STACK_OF(X509) *certs, |
|
92 xmlChar *subjectName, |
|
93 xmlChar *issuerName, |
|
94 xmlChar *issuerSerial, |
|
95 xmlChar *ski); |
|
96 static X509* xmlSecSymbianCryptoX509FindNextChainCert (STACK_OF(X509) *chain, |
|
97 X509 *cert); |
|
98 static int xmlSecSymbianCryptoX509VerifyCertAgainstCrls (STACK_OF(X509_CRL) *crls, |
|
99 X509* cert); |
|
100 static X509_NAME* xmlSecSymbianCryptoX509NameRead (xmlSecByte *str, |
|
101 int len); |
|
102 static int xmlSecSymbianCryptoX509NameStringRead (xmlSecByte **str, |
|
103 int *strLen, |
|
104 xmlSecByte *res, |
|
105 int resLen, |
|
106 xmlSecByte delim, |
|
107 int ingoreTrailingSpaces); |
|
108 static int xmlSecSymbianCryptoX509NamesCompare (X509_NAME *a, |
|
109 X509_NAME *b); |
|
110 static int xmlSecSymbianCryptoX509_NAME_cmp (const X509_NAME *a, |
|
111 const X509_NAME *b); |
|
112 /* |
|
113 static int xmlSecSymbianCryptoX509_NAME_ENTRY_cmp (const X509_NAME_ENTRY **a, |
|
114 const X509_NAME_ENTRY **b); |
|
115 */ |
|
116 /** |
|
117 * xmlSecSymbianCryptoX509StoreGetKlass: |
|
118 * |
|
119 * The SymbianCrypto X509 certificates key data store klass. |
|
120 * |
|
121 * Returns pointer to SymbianCrypto X509 certificates key data store klass. |
|
122 */ |
|
123 EXPORT_C |
|
124 xmlSecKeyDataStoreId |
|
125 xmlSecSymbianCryptoX509StoreGetKlass(void) { |
|
126 return(&xmlSecSymbianCryptoX509StoreKlass); |
|
127 } |
|
128 |
|
129 /** |
|
130 * xmlSecSymbianCryptoX509StoreFindCert: |
|
131 * @store: the pointer to X509 key data store klass. |
|
132 * @subjectName: the desired certificate name. |
|
133 * @issuerName: the desired certificate issuer name. |
|
134 * @issuerSerial: the desired certificate issuer serial number. |
|
135 * @ski: the desired certificate SKI. |
|
136 * @keyInfoCtx: the pointer to <dsig:KeyInfo/> element processing context. |
|
137 * |
|
138 * Searches @store for a certificate that matches given criteria. |
|
139 * |
|
140 * Returns pointer to found certificate or NULL if certificate is not found |
|
141 * or an error occurs. |
|
142 */ |
|
143 EXPORT_C |
|
144 X509* |
|
145 xmlSecSymbianCryptoX509StoreFindCert(xmlSecKeyDataStorePtr store, xmlChar *subjectName, |
|
146 xmlChar *issuerName, xmlChar *issuerSerial, |
|
147 xmlChar *ski, xmlSecKeyInfoCtx* keyInfoCtx) { |
|
148 xmlSecSymbianCryptoX509StoreCtxPtr ctx; |
|
149 X509* res = NULL; |
|
150 |
|
151 xmlSecAssert2(xmlSecKeyDataStoreCheckId(store, xmlSecSymbianCryptoX509StoreId), NULL); |
|
152 xmlSecAssert2(keyInfoCtx, NULL); |
|
153 |
|
154 ctx = xmlSecSymbianCryptoX509StoreGetCtx(store); |
|
155 xmlSecAssert2(ctx, NULL); |
|
156 |
|
157 if((!res) && (ctx->untrusted)) { |
|
158 res = xmlSecSymbianCryptoX509FindCert(ctx->untrusted, |
|
159 subjectName, |
|
160 issuerName, |
|
161 issuerSerial, |
|
162 ski); |
|
163 } |
|
164 return(res); |
|
165 } |
|
166 |
|
167 |
|
168 /** |
|
169 * xmlSecSymbianCryptoX509StoreVerify: |
|
170 * @store: the pointer to X509 key data store klass. |
|
171 * @cert: the untrusted key cert. |
|
172 * |
|
173 * Verifies @certs list. |
|
174 * |
|
175 * Returns Result of the verification |
|
176 */ |
|
177 EXPORT_C |
|
178 int |
|
179 xmlSecSymbianCryptoX509StoreKeyCertVerify(xmlSecKeyDataStorePtr store, X509* cert) { |
|
180 xmlSecSymbianCryptoX509StoreCtxPtr ctx; |
|
181 X509* res = NULL; |
|
182 X509 *err_cert = NULL; |
|
183 char buf[256]; |
|
184 int err = 0, depth; |
|
185 int i; |
|
186 int ret; |
|
187 |
|
188 xmlSecAssert2(xmlSecKeyDataStoreCheckId(store, xmlSecSymbianCryptoX509StoreId), NULL); |
|
189 xmlSecAssert2(cert, NULL); |
|
190 |
|
191 ctx = xmlSecSymbianCryptoX509StoreGetCtx(store); |
|
192 xmlSecAssert2(ctx, NULL); |
|
193 xmlSecAssert2(ctx->xst, NULL); |
|
194 |
|
195 if(!xmlSecCheckCertStoreFlag()) //SymbianCertStore Flag == FALSE |
|
196 { |
|
197 err = X509_STORE_certchain_init (ctx->xst, cert); |
|
198 if(err != 0) { |
|
199 xmlSecError(XMLSEC_ERRORS_HERE, |
|
200 xmlSecErrorsSafeString(xmlSecKeyDataStoreGetName(store)), |
|
201 "X509_STORE_certchain_init", |
|
202 XMLSEC_ERRORS_R_CRYPTO_FAILED, |
|
203 XMLSEC_ERRORS_NO_MESSAGE); |
|
204 //goto done; |
|
205 return -1; |
|
206 } |
|
207 err = X509_STORE_certchain_validate(ctx->xst); |
|
208 if(err != 0) { |
|
209 xmlSecError(XMLSEC_ERRORS_HERE, |
|
210 xmlSecErrorsSafeString(xmlSecKeyDataStoreGetName(store)), |
|
211 "X509_STORE_certchain_init", |
|
212 XMLSEC_ERRORS_R_CRYPTO_FAILED, |
|
213 XMLSEC_ERRORS_NO_MESSAGE); |
|
214 //goto done; |
|
215 return -1; |
|
216 } |
|
217 |
|
218 return X509_STORE_certchain_getValidateResult(ctx->xst); |
|
219 } |
|
220 else //SymbianCertStore Flag ==TRUE |
|
221 { |
|
222 err = X509_STORE_certchain_init_fromCertStore(ctx->xst, cert); |
|
223 if(err != 0) { |
|
224 xmlSecError(XMLSEC_ERRORS_HERE, |
|
225 xmlSecErrorsSafeString(xmlSecKeyDataStoreGetName(store)), |
|
226 "X509_STORE_certchain_init", |
|
227 XMLSEC_ERRORS_R_CRYPTO_FAILED, |
|
228 XMLSEC_ERRORS_NO_MESSAGE); |
|
229 //goto done; |
|
230 return -1; |
|
231 } |
|
232 err = X509_STORE_certchain_validate(ctx->xst); |
|
233 if(err != 0) { |
|
234 xmlSecError(XMLSEC_ERRORS_HERE, |
|
235 xmlSecErrorsSafeString(xmlSecKeyDataStoreGetName(store)), |
|
236 "X509_STORE_certchain_init", |
|
237 XMLSEC_ERRORS_R_CRYPTO_FAILED, |
|
238 XMLSEC_ERRORS_NO_MESSAGE); |
|
239 //goto done; |
|
240 return -1; |
|
241 } |
|
242 return X509_STORE_certchain_getValidateResult(ctx->xst); |
|
243 } //else |
|
244 } |
|
245 |
|
246 /** |
|
247 * xmlSecSymbianCryptoX509StoreVerify: |
|
248 * @store: the pointer to X509 key data store klass. |
|
249 * @certs: the untrusted certificates stack. |
|
250 * @crls: the crls stack. |
|
251 * @keyInfoCtx: the pointer to <dsig:KeyInfo/> element processing context. |
|
252 * |
|
253 * Verifies @certs list. |
|
254 * |
|
255 * Returns pointer to the first verified certificate from @certs. |
|
256 */ |
|
257 EXPORT_C |
|
258 X509* |
|
259 xmlSecSymbianCryptoX509StoreVerify(xmlSecKeyDataStorePtr store, XMLSEC_STACK_OF_X509* certs, |
|
260 XMLSEC_STACK_OF_X509_CRL* crls, xmlSecKeyInfoCtx* keyInfoCtx) { |
|
261 xmlSecSymbianCryptoX509StoreCtxPtr ctx; |
|
262 STACK_OF(X509)* certs2 = NULL; |
|
263 X509* res = NULL; |
|
264 X509* cert = NULL; |
|
265 X509 *err_cert = NULL; |
|
266 char buf[256]; |
|
267 int err = 0, depth; |
|
268 int i; |
|
269 int ret; |
|
270 |
|
271 xmlSecAssert2(xmlSecKeyDataStoreCheckId(store, xmlSecSymbianCryptoX509StoreId), NULL); |
|
272 xmlSecAssert2(certs, NULL); |
|
273 xmlSecAssert2(keyInfoCtx, NULL); |
|
274 |
|
275 ctx = xmlSecSymbianCryptoX509StoreGetCtx(store); |
|
276 xmlSecAssert2(ctx, NULL); |
|
277 xmlSecAssert2(ctx->xst, NULL); |
|
278 |
|
279 err = X509_STORE_certchain_init (ctx->xst, certs); |
|
280 if(err != 0) { |
|
281 xmlSecError(XMLSEC_ERRORS_HERE, |
|
282 xmlSecErrorsSafeString(xmlSecKeyDataStoreGetName(store)), |
|
283 "X509_STORE_certchain_init", |
|
284 XMLSEC_ERRORS_R_CRYPTO_FAILED, |
|
285 XMLSEC_ERRORS_NO_MESSAGE); |
|
286 } |
|
287 |
|
288 |
|
289 err = X509_STORE_certchain_validate(ctx->xst); |
|
290 if(err != 0) { |
|
291 xmlSecError(XMLSEC_ERRORS_HERE, |
|
292 xmlSecErrorsSafeString(xmlSecKeyDataStoreGetName(store)), |
|
293 "X509_STORE_certchain_init", |
|
294 XMLSEC_ERRORS_R_CRYPTO_FAILED, |
|
295 XMLSEC_ERRORS_NO_MESSAGE); |
|
296 } |
|
297 |
|
298 ret = X509_STORE_certchain_getValidateResult(ctx->xst); |
|
299 if(ret == 1) { |
|
300 res = cert; |
|
301 } |
|
302 |
|
303 #ifdef XMLSEC_FUTURE_SUPPORT |
|
304 /* dup certs */ |
|
305 /* |
|
306 certs2 = sk_X509_dup(certs); |
|
307 if(certs2 == NULL) { |
|
308 xmlSecError(XMLSEC_ERRORS_HERE, |
|
309 xmlSecErrorsSafeString(xmlSecKeyDataStoreGetName(store)), |
|
310 "sk_X509_dup", |
|
311 XMLSEC_ERRORS_R_CRYPTO_FAILED, |
|
312 XMLSEC_ERRORS_NO_MESSAGE); |
|
313 goto done; |
|
314 } |
|
315 */ |
|
316 /* add untrusted certs from the store */ |
|
317 #ifndef XMLSEC_NO_X509_UNTRUST |
|
318 if(ctx->untrusted) { |
|
319 for(i = 0; i < sk_X509_num(ctx->untrusted); ++i) { |
|
320 ret = sk_X509_push(certs2, sk_X509_value(ctx->untrusted, i)); |
|
321 if(ret < 1) { |
|
322 xmlSecError(XMLSEC_ERRORS_HERE, |
|
323 xmlSecErrorsSafeString(xmlSecKeyDataStoreGetName(store)), |
|
324 "sk_X509_push", |
|
325 XMLSEC_ERRORS_R_CRYPTO_FAILED, |
|
326 XMLSEC_ERRORS_NO_MESSAGE); |
|
327 goto done; |
|
328 } |
|
329 } |
|
330 } |
|
331 #endif //XMLSEC_NO_X509_UNTRUST |
|
332 |
|
333 #ifndef XMLSEC_NO_X509_CRL |
|
334 /* dup crls but remove all non-verified */ |
|
335 if(crls) { |
|
336 crls2 = sk_X509_CRL_dup(crls); |
|
337 if(!crls2) { |
|
338 xmlSecError(XMLSEC_ERRORS_HERE, |
|
339 xmlSecErrorsSafeString(xmlSecKeyDataStoreGetName(store)), |
|
340 "sk_X509_CRL_dup", |
|
341 XMLSEC_ERRORS_R_CRYPTO_FAILED, |
|
342 XMLSEC_ERRORS_NO_MESSAGE); |
|
343 goto done; |
|
344 } |
|
345 |
|
346 for(i = 0; i < sk_X509_CRL_num(crls2); ) { |
|
347 ret = xmlSecSymbianCryptoX509VerifyCrl(ctx->xst, sk_X509_CRL_value(crls2, i)); |
|
348 if(ret == 1) { |
|
349 ++i; |
|
350 } else if(ret == 0) { |
|
351 sk_X509_CRL_delete(crls2, i); |
|
352 } else { |
|
353 xmlSecError(XMLSEC_ERRORS_HERE, |
|
354 xmlSecErrorsSafeString(xmlSecKeyDataStoreGetName(store)), |
|
355 "xmlSecSymbianCryptoX509VerifyCrl", |
|
356 XMLSEC_ERRORS_R_XMLSEC_FAILED, |
|
357 XMLSEC_ERRORS_NO_MESSAGE); |
|
358 goto done; |
|
359 } |
|
360 } |
|
361 } |
|
362 |
|
363 /* remove all revoked certs */ |
|
364 for(i = 0; i < sk_X509_num(certs2);) { |
|
365 cert = sk_X509_value(certs2, i); |
|
366 |
|
367 if(crls2) { |
|
368 ret = xmlSecSymbianCryptoX509VerifyCertAgainstCrls(crls2, cert); |
|
369 if(ret == 0) { |
|
370 sk_X509_delete(certs2, i); |
|
371 continue; |
|
372 } else if(ret != 1) { |
|
373 xmlSecError(XMLSEC_ERRORS_HERE, |
|
374 xmlSecErrorsSafeString(xmlSecKeyDataStoreGetName(store)), |
|
375 "xmlSecSymbianCryptoX509VerifyCertAgainstCrls", |
|
376 XMLSEC_ERRORS_R_XMLSEC_FAILED, |
|
377 XMLSEC_ERRORS_NO_MESSAGE); |
|
378 goto done; |
|
379 } |
|
380 } |
|
381 |
|
382 if(ctx->crls) { |
|
383 ret = xmlSecSymbianCryptoX509VerifyCertAgainstCrls(ctx->crls, cert); |
|
384 if(ret == 0) { |
|
385 sk_X509_delete(certs2, i); |
|
386 continue; |
|
387 } else if(ret != 1) { |
|
388 xmlSecError(XMLSEC_ERRORS_HERE, |
|
389 xmlSecErrorsSafeString(xmlSecKeyDataStoreGetName(store)), |
|
390 "xmlSecSymbianCryptoX509VerifyCertAgainstCrls", |
|
391 XMLSEC_ERRORS_R_XMLSEC_FAILED, |
|
392 XMLSEC_ERRORS_NO_MESSAGE); |
|
393 goto done; |
|
394 } |
|
395 } |
|
396 ++i; |
|
397 } |
|
398 |
|
399 #endif //XMLSEC_NO_X509_CRL |
|
400 |
|
401 /* get one cert after another and try to verify */ |
|
402 for(i = 0; i < sk_X509_num(certs2); ++i) { |
|
403 cert = sk_X509_value(certs2, i); |
|
404 if(!xmlSecSymbianCryptoX509FindNextChainCert(certs2, cert)) { |
|
405 X509_STORE_CTX xsc; |
|
406 |
|
407 #if !defined(XMLSEC_OPENSSL_096) && !defined(XMLSEC_OPENSSL_097) |
|
408 X509_VERIFY_PARAM * vpm = NULL; |
|
409 unsigned long vpm_flags = 0; |
|
410 |
|
411 vpm = X509_VERIFY_PARAM_new(); |
|
412 if(!vpm) { |
|
413 xmlSecError(XMLSEC_ERRORS_HERE, |
|
414 xmlSecErrorsSafeString(xmlSecKeyDataStoreGetName(store)), |
|
415 "X509_VERIFY_PARAM_new", |
|
416 XMLSEC_ERRORS_R_CRYPTO_FAILED, |
|
417 XMLSEC_ERRORS_NO_MESSAGE); |
|
418 goto done; |
|
419 } |
|
420 vpm_flags = vpm->flags; |
|
421 /* |
|
422 vpm_flags &= (~X509_V_FLAG_X509_STRICT); |
|
423 */ |
|
424 vpm_flags &= (~X509_V_FLAG_CRL_CHECK); |
|
425 |
|
426 X509_VERIFY_PARAM_set_depth(vpm, 9); |
|
427 X509_VERIFY_PARAM_set_flags(vpm, vpm_flags); |
|
428 #endif /* !defined(XMLSEC_OPENSSL_096) && !defined(XMLSEC_OPENSSL_097) */ |
|
429 |
|
430 |
|
431 X509_STORE_CTX_init (&xsc, ctx->xst, cert, certs2); |
|
432 |
|
433 if(keyInfoCtx->certsVerificationTime > 0) { |
|
434 #if !defined(XMLSEC_OPENSSL_096) && !defined(XMLSEC_OPENSSL_097) |
|
435 vpm_flags |= X509_V_FLAG_USE_CHECK_TIME; |
|
436 X509_VERIFY_PARAM_set_time(vpm, keyInfoCtx->certsVerificationTime); |
|
437 #endif /* !defined(XMLSEC_OPENSSL_096) && !defined(XMLSEC_OPENSSL_097) */ |
|
438 X509_STORE_CTX_set_time(&xsc, 0, keyInfoCtx->certsVerificationTime); |
|
439 } |
|
440 |
|
441 #if !defined(XMLSEC_OPENSSL_096) && !defined(XMLSEC_OPENSSL_097) |
|
442 X509_STORE_CTX_set0_param(&xsc, vpm); |
|
443 #endif /* !defined(XMLSEC_OPENSSL_096) && !defined(XMLSEC_OPENSSL_097) */ |
|
444 |
|
445 |
|
446 ret = X509_verify_cert(&xsc); |
|
447 err_cert = X509_STORE_CTX_get_current_cert(&xsc); |
|
448 err = X509_STORE_CTX_get_error(&xsc); |
|
449 depth = X509_STORE_CTX_get_error_depth(&xsc); |
|
450 |
|
451 X509_STORE_CTX_cleanup (&xsc); |
|
452 |
|
453 if(ret == 1) { |
|
454 res = cert; |
|
455 goto done; |
|
456 } else if(ret < 0) { |
|
457 const char* err_msg; |
|
458 |
|
459 buf[0] = '\0'; |
|
460 X509_NAME_oneline(X509_get_subject_name(err_cert), buf, sizeof buf); |
|
461 err_msg = X509_verify_cert_error_string(err); |
|
462 xmlSecError(XMLSEC_ERRORS_HERE, |
|
463 xmlSecErrorsSafeString(xmlSecKeyDataStoreGetName(store)), |
|
464 "X509_verify_cert", |
|
465 XMLSEC_ERRORS_R_CRYPTO_FAILED, |
|
466 "subj=%s;err=%d;msg=%s", |
|
467 xmlSecErrorsSafeString(buf), |
|
468 err, |
|
469 xmlSecErrorsSafeString(err_msg)); |
|
470 goto done; |
|
471 } else if(ret == 0) { |
|
472 const char* err_msg; |
|
473 |
|
474 buf[0] = '\0'; |
|
475 X509_NAME_oneline(X509_get_subject_name(err_cert), buf, sizeof buf); |
|
476 err_msg = X509_verify_cert_error_string(err); |
|
477 xmlSecError(XMLSEC_ERRORS_HERE, |
|
478 xmlSecErrorsSafeString(xmlSecKeyDataStoreGetName(store)), |
|
479 "X509_verify_cert", |
|
480 XMLSEC_ERRORS_R_CRYPTO_FAILED, |
|
481 "subj=%s;err=%d;msg=%s", |
|
482 xmlSecErrorsSafeString(buf), |
|
483 err, |
|
484 xmlSecErrorsSafeString(err_msg)); |
|
485 } |
|
486 } |
|
487 } |
|
488 |
|
489 /* if we came here then we found nothing. do we have any error? */ |
|
490 if((err != 0) && (err_cert)) { |
|
491 const char* err_msg; |
|
492 |
|
493 err_msg = X509_verify_cert_error_string(err); |
|
494 switch (err) { |
|
495 case X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT: |
|
496 X509_NAME_oneline(X509_get_issuer_name(err_cert), buf, sizeof buf); |
|
497 xmlSecError(XMLSEC_ERRORS_HERE, |
|
498 xmlSecErrorsSafeString(xmlSecKeyDataStoreGetName(store)), |
|
499 NULL, |
|
500 XMLSEC_ERRORS_R_CERT_ISSUER_FAILED, |
|
501 "err=%d;msg=%s;issuer=%s", |
|
502 err, |
|
503 xmlSecErrorsSafeString(err_msg), |
|
504 xmlSecErrorsSafeString(buf)); |
|
505 break; |
|
506 case X509_V_ERR_CERT_NOT_YET_VALID: |
|
507 case X509_V_ERR_ERROR_IN_CERT_NOT_BEFORE_FIELD: |
|
508 xmlSecError(XMLSEC_ERRORS_HERE, |
|
509 xmlSecErrorsSafeString(xmlSecKeyDataStoreGetName(store)), |
|
510 NULL, |
|
511 XMLSEC_ERRORS_R_CERT_NOT_YET_VALID, |
|
512 "err=%d;msg=%s", err, |
|
513 xmlSecErrorsSafeString(err_msg)); |
|
514 break; |
|
515 case X509_V_ERR_CERT_HAS_EXPIRED: |
|
516 case X509_V_ERR_ERROR_IN_CERT_NOT_AFTER_FIELD: |
|
517 xmlSecError(XMLSEC_ERRORS_HERE, |
|
518 xmlSecErrorsSafeString(xmlSecKeyDataStoreGetName(store)), |
|
519 NULL, |
|
520 XMLSEC_ERRORS_R_CERT_HAS_EXPIRED, |
|
521 "err=%d;msg=%s", err, |
|
522 xmlSecErrorsSafeString(err_msg)); |
|
523 break; |
|
524 default: |
|
525 xmlSecError(XMLSEC_ERRORS_HERE, |
|
526 xmlSecErrorsSafeString(xmlSecKeyDataStoreGetName(store)), |
|
527 NULL, |
|
528 XMLSEC_ERRORS_R_CERT_VERIFY_FAILED, |
|
529 "err=%d;msg=%s", err, |
|
530 xmlSecErrorsSafeString(err_msg)); |
|
531 } |
|
532 } |
|
533 |
|
534 done: |
|
535 |
|
536 if(certs2) { |
|
537 X509_free(certs2); |
|
538 } |
|
539 if(crls2) { |
|
540 sk_X509_CRL_free(crls2); |
|
541 } |
|
542 |
|
543 #endif //XMLSEC_FUTURE_SUPPORT |
|
544 return(res); |
|
545 } |
|
546 |
|
547 /** |
|
548 * xmlSecSymbianCryptoX509StoreAdoptCert: |
|
549 * @store: the pointer to X509 key data store klass. |
|
550 * @cert: the pointer to SymbianCrypto X509 certificate. |
|
551 * @type: the certificate type (trusted/untrusted). |
|
552 * |
|
553 * Adds trusted (root) or untrusted certificate to the store. |
|
554 * |
|
555 * Returns 0 on success or a negative value if an error occurs. |
|
556 */ |
|
557 EXPORT_C |
|
558 int |
|
559 xmlSecSymbianCryptoX509StoreAdoptCert(xmlSecKeyDataStorePtr store, |
|
560 X509* cert, |
|
561 xmlSecKeyDataType type) { |
|
562 xmlSecSymbianCryptoX509StoreCtxPtr ctx; |
|
563 int ret = -1; |
|
564 |
|
565 xmlSecAssert2(xmlSecKeyDataStoreCheckId(store, xmlSecSymbianCryptoX509StoreId), -1); |
|
566 xmlSecAssert2(cert, -1); |
|
567 |
|
568 ctx = xmlSecSymbianCryptoX509StoreGetCtx(store); |
|
569 xmlSecAssert2(ctx, -1); |
|
570 |
|
571 if((type & xmlSecKeyDataTypeTrusted) != 0) { |
|
572 xmlSecAssert2(ctx->xst, -1); |
|
573 |
|
574 ret = X509_STORE_add_cert(ctx->xst, cert); |
|
575 if(ret != 0) { |
|
576 xmlSecError(XMLSEC_ERRORS_HERE, |
|
577 xmlSecErrorsSafeString(xmlSecKeyDataStoreGetName(store)), |
|
578 "X509_STORE_add_cert", |
|
579 XMLSEC_ERRORS_R_CRYPTO_FAILED, |
|
580 XMLSEC_ERRORS_NO_MESSAGE); |
|
581 xmlSecSetErrorFlag( ret ); |
|
582 return(-1); |
|
583 } |
|
584 /* add cert increments the reference */ |
|
585 X509_free(cert); |
|
586 } else { |
|
587 xmlSecAssert2(ctx->untrusted, -1); |
|
588 |
|
589 if(ret < 1) { |
|
590 xmlSecError(XMLSEC_ERRORS_HERE, |
|
591 xmlSecErrorsSafeString(xmlSecKeyDataStoreGetName(store)), |
|
592 "sk_X509_push", |
|
593 XMLSEC_ERRORS_R_CRYPTO_FAILED, |
|
594 XMLSEC_ERRORS_NO_MESSAGE); |
|
595 return(-1); |
|
596 } |
|
597 } |
|
598 return(0); |
|
599 } |
|
600 |
|
601 /** |
|
602 * xmlSecSymbianCryptoX509StoreAddCertsPath: |
|
603 * @store: the pointer to SymbianCrypto x509 store. |
|
604 * @path: the path to the certs dir. |
|
605 * |
|
606 * Adds all certs in the @path to the list of trusted certs |
|
607 * in @store. |
|
608 * |
|
609 * Returns 0 on success or a negative value otherwise. |
|
610 */ |
|
611 EXPORT_C |
|
612 int |
|
613 xmlSecSymbianCryptoX509StoreAddCertsPath(xmlSecKeyDataStorePtr store, const char *path) { |
|
614 xmlSecSymbianCryptoX509StoreCtxPtr ctx; |
|
615 |
|
616 xmlSecAssert2(xmlSecKeyDataStoreCheckId(store, xmlSecSymbianCryptoX509StoreId), -1); |
|
617 xmlSecAssert2(path, -1); |
|
618 |
|
619 ctx = xmlSecSymbianCryptoX509StoreGetCtx(store); |
|
620 xmlSecAssert2(ctx, -1); |
|
621 xmlSecAssert2(ctx->xst, -1); |
|
622 /* |
|
623 lookup = X509_STORE_add_lookup(ctx->xst, X509_LOOKUP_hash_dir()); |
|
624 if(lookup == NULL) { |
|
625 xmlSecError(XMLSEC_ERRORS_HERE, |
|
626 xmlSecErrorsSafeString(xmlSecKeyDataStoreGetName(store)), |
|
627 "X509_STORE_add_lookup", |
|
628 XMLSEC_ERRORS_R_CRYPTO_FAILED, |
|
629 XMLSEC_ERRORS_NO_MESSAGE); |
|
630 return(-1); |
|
631 } |
|
632 X509_LOOKUP_add_dir(lookup, path, X509_FILETYPE_DEFAULT); |
|
633 */ |
|
634 return(0); |
|
635 } |
|
636 |
|
637 static int |
|
638 xmlSecSymbianCryptoX509StoreInitialize(xmlSecKeyDataStorePtr store) { |
|
639 const xmlChar* path; |
|
640 |
|
641 xmlSecSymbianCryptoX509StoreCtxPtr ctx; |
|
642 xmlSecAssert2(xmlSecKeyDataStoreCheckId(store, xmlSecSymbianCryptoX509StoreId), -1); |
|
643 |
|
644 ctx = xmlSecSymbianCryptoX509StoreGetCtx(store); |
|
645 xmlSecAssert2(ctx, -1); |
|
646 |
|
647 memset(ctx, 0, sizeof(xmlSecSymbianCryptoX509StoreCtx)); |
|
648 |
|
649 ctx->xst = X509_STORE_new(); |
|
650 if(!ctx->xst) { |
|
651 xmlSecError(XMLSEC_ERRORS_HERE, |
|
652 xmlSecErrorsSafeString(xmlSecKeyDataStoreGetName(store)), |
|
653 "X509_STORE_new", |
|
654 XMLSEC_ERRORS_R_CRYPTO_FAILED, |
|
655 XMLSEC_ERRORS_NO_MESSAGE); |
|
656 return(-1); |
|
657 } |
|
658 #ifdef XMLSEC_FUTURE_SUPPORT |
|
659 if(!X509_STORE_set_default_paths(ctx->xst)) { |
|
660 xmlSecError(XMLSEC_ERRORS_HERE, |
|
661 xmlSecErrorsSafeString(xmlSecKeyDataStoreGetName(store)), |
|
662 "X509_STORE_set_default_paths", |
|
663 XMLSEC_ERRORS_R_CRYPTO_FAILED, |
|
664 XMLSEC_ERRORS_NO_MESSAGE); |
|
665 return(-1); |
|
666 } |
|
667 |
|
668 path = xmlSecSymbianCryptoGetDefaultTrustedCertsFolder(); |
|
669 if(path) { |
|
670 X509_LOOKUP *lookup = NULL; |
|
671 |
|
672 lookup = X509_STORE_add_lookup(ctx->xst, X509_LOOKUP_hash_dir()); |
|
673 if(!lookup) { |
|
674 xmlSecError(XMLSEC_ERRORS_HERE, |
|
675 xmlSecErrorsSafeString(xmlSecKeyDataStoreGetName(store)), |
|
676 "X509_STORE_add_lookup", |
|
677 XMLSEC_ERRORS_R_CRYPTO_FAILED, |
|
678 XMLSEC_ERRORS_NO_MESSAGE); |
|
679 return(-1); |
|
680 } |
|
681 X509_LOOKUP_add_dir(lookup, (char*)path, X509_FILETYPE_DEFAULT); |
|
682 } |
|
683 |
|
684 ctx->untrusted = sk_X509_new_null(); |
|
685 if(!ctx->untrusted) { |
|
686 xmlSecError(XMLSEC_ERRORS_HERE, |
|
687 xmlSecErrorsSafeString(xmlSecKeyDataStoreGetName(store)), |
|
688 "sk_X509_new_null", |
|
689 XMLSEC_ERRORS_R_CRYPTO_FAILED, |
|
690 XMLSEC_ERRORS_NO_MESSAGE); |
|
691 return(-1); |
|
692 } |
|
693 |
|
694 ctx->crls = sk_X509_CRL_new_null(); |
|
695 if(!ctx->crls) { |
|
696 xmlSecError(XMLSEC_ERRORS_HERE, |
|
697 xmlSecErrorsSafeString(xmlSecKeyDataStoreGetName(store)), |
|
698 "sk_X509_CRL_new_null", |
|
699 XMLSEC_ERRORS_R_CRYPTO_FAILED, |
|
700 XMLSEC_ERRORS_NO_MESSAGE); |
|
701 return(-1); |
|
702 } |
|
703 |
|
704 #if !defined(XMLSEC_OPENSSL_096) && !defined(XMLSEC_OPENSSL_097) |
|
705 ctx->vpm = X509_VERIFY_PARAM_new(); |
|
706 if(!ctx->vpm) { |
|
707 xmlSecError(XMLSEC_ERRORS_HERE, |
|
708 xmlSecErrorsSafeString(xmlSecKeyDataStoreGetName(store)), |
|
709 "X509_VERIFY_PARAM_new", |
|
710 XMLSEC_ERRORS_R_CRYPTO_FAILED, |
|
711 XMLSEC_ERRORS_NO_MESSAGE); |
|
712 return(-1); |
|
713 } |
|
714 X509_VERIFY_PARAM_set_depth(ctx->vpm, 9); /* the default cert verification path in openssl */ |
|
715 X509_STORE_set1_param(ctx->xst, ctx->vpm); |
|
716 |
|
717 #else /* !defined(XMLSEC_OPENSSL_096) && !defined(XMLSEC_OPENSSL_097) */ |
|
718 ctx->xst->depth = 9; /* the default cert verification path in openssl */ |
|
719 #endif /* !defined(XMLSEC_OPENSSL_096) && !defined(XMLSEC_OPENSSL_097) */ |
|
720 |
|
721 #endif //XMLSEC_FUTURE_SUPPORT |
|
722 return(0); |
|
723 } |
|
724 |
|
725 static void |
|
726 xmlSecSymbianCryptoX509StoreFinalize(xmlSecKeyDataStorePtr store) { |
|
727 xmlSecSymbianCryptoX509StoreCtxPtr ctx; |
|
728 xmlSecAssert(xmlSecKeyDataStoreCheckId(store, xmlSecSymbianCryptoX509StoreId)); |
|
729 |
|
730 ctx = xmlSecSymbianCryptoX509StoreGetCtx(store); |
|
731 xmlSecAssert(ctx); |
|
732 |
|
733 if(ctx->xst) { |
|
734 X509_STORE_free(ctx->xst); |
|
735 } |
|
736 if(ctx->untrusted) { |
|
737 } |
|
738 if(ctx->crls) { |
|
739 } |
|
740 #if !defined(XMLSEC_OPENSSL_096) && !defined(XMLSEC_OPENSSL_097) |
|
741 if(ctx->vpm) { |
|
742 X509_VERIFY_PARAM_free(ctx->vpm); |
|
743 } |
|
744 #endif /* !defined(XMLSEC_OPENSSL_096) && !defined(XMLSEC_OPENSSL_097) */ |
|
745 memset(ctx, 0, sizeof(xmlSecSymbianCryptoX509StoreCtx)); |
|
746 } |
|
747 |
|
748 |
|
749 /***************************************************************************** |
|
750 * |
|
751 * Low-level x509 functions |
|
752 * |
|
753 *****************************************************************************/ |
|
754 static int |
|
755 xmlSecSymbianCryptoX509VerifyCrl(X509_STORE* xst, X509_CRL *crl ) { |
|
756 |
|
757 EVP_PKEY *pkey; |
|
758 int ret = 0; |
|
759 #ifdef XMLSEC_FUTURE_SUPPORT |
|
760 xmlSecAssert2(xst, -1); |
|
761 xmlSecAssert2(crl, -1); |
|
762 |
|
763 X509_STORE_CTX_init(&xsc, xst, NULL, NULL); |
|
764 ret = X509_STORE_get_by_subject(&xsc, X509_LU_X509, |
|
765 X509_CRL_get_issuer(crl), &xobj); |
|
766 if(ret <= 0) { |
|
767 xmlSecError(XMLSEC_ERRORS_HERE, |
|
768 NULL, |
|
769 "X509_STORE_get_by_subject", |
|
770 XMLSEC_ERRORS_R_CRYPTO_FAILED, |
|
771 XMLSEC_ERRORS_NO_MESSAGE); |
|
772 return(-1); |
|
773 } |
|
774 pkey = X509_get_pubkey(xobj.data.x509); |
|
775 X509_OBJECT_free_contents(&xobj); |
|
776 if(!pkey) { |
|
777 xmlSecError(XMLSEC_ERRORS_HERE, |
|
778 NULL, |
|
779 "X509_get_pubkey", |
|
780 XMLSEC_ERRORS_R_CRYPTO_FAILED, |
|
781 XMLSEC_ERRORS_NO_MESSAGE); |
|
782 return(-1); |
|
783 } |
|
784 ret = X509_CRL_verify(crl, pkey); |
|
785 EVP_PKEY_free(pkey); |
|
786 if(ret != 1) { |
|
787 xmlSecError(XMLSEC_ERRORS_HERE, |
|
788 NULL, |
|
789 "X509_CRL_verify", |
|
790 XMLSEC_ERRORS_R_CRYPTO_FAILED, |
|
791 XMLSEC_ERRORS_NO_MESSAGE); |
|
792 } |
|
793 X509_STORE_CTX_cleanup (&xsc); |
|
794 #endif //XMLSEC_FUTURE_SUPPORT |
|
795 return((ret == 1) ? 1 : 0); |
|
796 } |
|
797 |
|
798 /** |
|
799 * xmlSecSymbianCryptoX509FindCert: |
|
800 */ |
|
801 static X509* |
|
802 xmlSecSymbianCryptoX509FindCert(STACK_OF(X509) *certs, xmlChar *subjectName, |
|
803 xmlChar *issuerName, xmlChar *issuerSerial, |
|
804 xmlChar *ski) { |
|
805 X509 *cert = NULL; |
|
806 int i; |
|
807 |
|
808 xmlSecAssert2(certs, NULL); |
|
809 #ifdef XMLSEC_FUTURE_SUPPORT |
|
810 /* may be this is not the fastest way to search certs */ |
|
811 if(subjectName) { |
|
812 X509_NAME *nm; |
|
813 X509_NAME *subj; |
|
814 |
|
815 nm = xmlSecSymbianCryptoX509NameRead(subjectName, xmlStrlen(subjectName)); |
|
816 if(!nm) { |
|
817 xmlSecError(XMLSEC_ERRORS_HERE, |
|
818 NULL, |
|
819 "xmlSecSymbianCryptoX509NameRead", |
|
820 XMLSEC_ERRORS_R_XMLSEC_FAILED, |
|
821 "subject=%s", |
|
822 xmlSecErrorsSafeString(subjectName)); |
|
823 return(NULL); |
|
824 } |
|
825 |
|
826 for(i = 0; i < certs->num; ++i) { |
|
827 cert = ((X509**)(certs->data))[i]; |
|
828 subj = X509_get_subject_name(cert); |
|
829 if(xmlSecSymbianCryptoX509NamesCompare(nm, subj) == 0) { |
|
830 X509_NAME_free(nm); |
|
831 return(cert); |
|
832 } |
|
833 } |
|
834 X509_NAME_free(nm); |
|
835 } else if((issuerName) && (issuerSerial)) { |
|
836 X509_NAME *nm; |
|
837 X509_NAME *issuer; |
|
838 BIGNUM *bn; |
|
839 ASN1_INTEGER *serial; |
|
840 |
|
841 nm = xmlSecSymbianCryptoX509NameRead(issuerName, xmlStrlen(issuerName)); |
|
842 if(!nm) { |
|
843 xmlSecError(XMLSEC_ERRORS_HERE, |
|
844 NULL, |
|
845 "xmlSecSymbianCryptoX509NameRead", |
|
846 XMLSEC_ERRORS_R_XMLSEC_FAILED, |
|
847 "issuer=%s", |
|
848 xmlSecErrorsSafeString(issuerName)); |
|
849 return(NULL); |
|
850 } |
|
851 |
|
852 bn = BN_new(); |
|
853 if(!bn) { |
|
854 xmlSecError(XMLSEC_ERRORS_HERE, |
|
855 NULL, |
|
856 "BN_new", |
|
857 XMLSEC_ERRORS_R_CRYPTO_FAILED, |
|
858 XMLSEC_ERRORS_NO_MESSAGE); |
|
859 X509_NAME_free(nm); |
|
860 return(NULL); |
|
861 } |
|
862 if(BN_dec2bn(&bn, (char*)issuerSerial) == 0) { |
|
863 xmlSecError(XMLSEC_ERRORS_HERE, |
|
864 NULL, |
|
865 "BN_dec2bn", |
|
866 XMLSEC_ERRORS_R_CRYPTO_FAILED, |
|
867 XMLSEC_ERRORS_NO_MESSAGE); |
|
868 BN_free(bn); |
|
869 X509_NAME_free(nm); |
|
870 return(NULL); |
|
871 } |
|
872 |
|
873 serial = BN_to_ASN1_INTEGER(bn, NULL); |
|
874 if(!serial) { |
|
875 xmlSecError(XMLSEC_ERRORS_HERE, |
|
876 NULL, |
|
877 "BN_to_ASN1_INTEGER", |
|
878 XMLSEC_ERRORS_R_CRYPTO_FAILED, |
|
879 XMLSEC_ERRORS_NO_MESSAGE); |
|
880 BN_free(bn); |
|
881 X509_NAME_free(nm); |
|
882 return(NULL); |
|
883 } |
|
884 BN_free(bn); |
|
885 |
|
886 |
|
887 for(i = 0; i < certs->num; ++i) { |
|
888 cert = ((X509**)(certs->data))[i]; |
|
889 if(ASN1_INTEGER_cmp(X509_get_serialNumber(cert), serial) != 0) { |
|
890 continue; |
|
891 } |
|
892 issuer = X509_get_issuer_name(cert); |
|
893 if(xmlSecSymbianCryptoX509NamesCompare(nm, issuer) == 0) { |
|
894 ASN1_INTEGER_free(serial); |
|
895 X509_NAME_free(nm); |
|
896 return(cert); |
|
897 } |
|
898 } |
|
899 |
|
900 X509_NAME_free(nm); |
|
901 ASN1_INTEGER_free(serial); |
|
902 } else if(ski) { |
|
903 int len; |
|
904 int index; |
|
905 X509_EXTENSION *ext; |
|
906 ASN1_OCTET_STRING *keyId; |
|
907 |
|
908 /* our usual trick with base64 decode */ |
|
909 len = xmlSecBase64Decode(ski, (xmlSecByte*)ski, xmlStrlen(ski)); |
|
910 if(len < 0) { |
|
911 xmlSecError(XMLSEC_ERRORS_HERE, |
|
912 NULL, |
|
913 "xmlSecBase64Decode", |
|
914 XMLSEC_ERRORS_R_XMLSEC_FAILED, |
|
915 "ski=%s", |
|
916 xmlSecErrorsSafeString(ski)); |
|
917 return(NULL); |
|
918 } |
|
919 for(i = 0; i < certs->num; ++i) { |
|
920 cert = ((X509**)(certs->data))[i]; |
|
921 index = X509_get_ext_by_NID(cert, NID_subject_key_identifier, -1); |
|
922 if(index >= 0) { |
|
923 ext = X509_get_ext(cert, index); |
|
924 if(ext){ |
|
925 keyId = X509V3_EXT_d2i(ext); |
|
926 if((keyId) && (keyId->length == len) && |
|
927 (memcmp(keyId->data, ski, len) == 0)) { |
|
928 M_ASN1_OCTET_STRING_free(keyId); |
|
929 return(cert); |
|
930 } |
|
931 M_ASN1_OCTET_STRING_free(keyId); |
|
932 } |
|
933 } |
|
934 } |
|
935 } |
|
936 #endif //XMLSEC_FUTURE_SUPPORT |
|
937 return(NULL); |
|
938 } |
|
939 |
|
940 /** |
|
941 * xmlSecSymbianCryptoX509FindNextChainCert: |
|
942 */ |
|
943 static X509* |
|
944 xmlSecSymbianCryptoX509FindNextChainCert(STACK_OF(X509) *chain, X509 *cert) { |
|
945 unsigned long certSubjHash; |
|
946 int i; |
|
947 |
|
948 xmlSecAssert2(chain, NULL); |
|
949 xmlSecAssert2(cert, NULL); |
|
950 /* |
|
951 certSubjHash = X509_subject_name_hash(cert); |
|
952 for(i = 0; i < sk_X509_num(chain); ++i) { |
|
953 if((sk_X509_value(chain, i) != cert) && |
|
954 (X509_issuer_name_hash(sk_X509_value(chain, i)) == certSubjHash)) { |
|
955 |
|
956 return(sk_X509_value(chain, i)); |
|
957 } |
|
958 } |
|
959 */ |
|
960 return(NULL); |
|
961 } |
|
962 |
|
963 /** |
|
964 * xmlSecSymbianCryptoX509VerifyCertAgainstCrls: |
|
965 */ |
|
966 static int |
|
967 xmlSecSymbianCryptoX509VerifyCertAgainstCrls(STACK_OF(X509_CRL) *crls, X509* cert) { |
|
968 X509_NAME *issuer; |
|
969 X509_CRL *crl = NULL; |
|
970 #ifdef XMLSEC_FUTURE_SUPPORT |
|
971 X509_REVOKED *revoked; |
|
972 int i, n; |
|
973 int ret; |
|
974 |
|
975 xmlSecAssert2(crls, -1); |
|
976 xmlSecAssert2(cert, -1); |
|
977 |
|
978 /* |
|
979 * Try to retrieve a CRL corresponding to the issuer of |
|
980 * the current certificate |
|
981 */ |
|
982 n = sk_X509_CRL_num(crls); |
|
983 for(i = 0; i < n; i++) { |
|
984 crl = sk_X509_CRL_value(crls, i); |
|
985 issuer = X509_CRL_get_issuer(crl); |
|
986 if(xmlSecSymbianCryptoX509NamesCompare(X509_CRL_get_issuer(crl), issuer) == 0) { |
|
987 break; |
|
988 } |
|
989 } |
|
990 if((i >= n) || (!crl)){ |
|
991 /* no crls for this issuer */ |
|
992 return(1); |
|
993 } |
|
994 |
|
995 /* |
|
996 * Check date of CRL to make sure it's not expired |
|
997 */ |
|
998 ret = X509_cmp_current_time(X509_CRL_get_nextUpdate(crl)); |
|
999 if (ret == 0) { |
|
1000 /* crl expired */ |
|
1001 return(1); |
|
1002 } |
|
1003 |
|
1004 /* |
|
1005 * Check if the current certificate is revoked by this CRL |
|
1006 */ |
|
1007 n = sk_num(X509_CRL_get_REVOKED(crl)); |
|
1008 for (i = 0; i < n; i++) { |
|
1009 revoked = (X509_REVOKED *)sk_value(X509_CRL_get_REVOKED(crl), i); |
|
1010 if (ASN1_INTEGER_cmp(revoked->serialNumber, X509_get_serialNumber(cert)) == 0) { |
|
1011 xmlSecError(XMLSEC_ERRORS_HERE, |
|
1012 NULL, |
|
1013 NULL, |
|
1014 XMLSEC_ERRORS_R_CERT_REVOKED, |
|
1015 XMLSEC_ERRORS_NO_MESSAGE); |
|
1016 return(0); |
|
1017 } |
|
1018 } |
|
1019 #endif //XMLSEC_FUTURE_SUPPORT |
|
1020 return(1); |
|
1021 } |
|
1022 |
|
1023 |
|
1024 /** |
|
1025 * xmlSecSymbianCryptoX509NameRead: |
|
1026 */ |
|
1027 static X509_NAME * |
|
1028 xmlSecSymbianCryptoX509NameRead(xmlSecByte *str, int len) { |
|
1029 xmlSecByte name[256]; |
|
1030 xmlSecByte value[256]; |
|
1031 int nameLen, valueLen; |
|
1032 X509_NAME *nm = NULL; |
|
1033 |
|
1034 xmlSecAssert2(str, NULL); |
|
1035 |
|
1036 #ifdef XMLSEC_FUTURE_SUPPORT |
|
1037 nm = X509_NAME_new(); |
|
1038 if(!nm) { |
|
1039 xmlSecError(XMLSEC_ERRORS_HERE, |
|
1040 NULL, |
|
1041 "X509_NAME_new", |
|
1042 XMLSEC_ERRORS_R_CRYPTO_FAILED, |
|
1043 XMLSEC_ERRORS_NO_MESSAGE); |
|
1044 return(NULL); |
|
1045 } |
|
1046 |
|
1047 while(len > 0) { |
|
1048 /* skip spaces after comma or semicolon */ |
|
1049 while((len > 0) && isspace(*str)) { |
|
1050 ++str; --len; |
|
1051 } |
|
1052 |
|
1053 nameLen = xmlSecSymbianCryptoX509NameStringRead(&str, &len, name, sizeof(name), '=', 0); |
|
1054 if(nameLen < 0) { |
|
1055 xmlSecError(XMLSEC_ERRORS_HERE, |
|
1056 NULL, |
|
1057 "xmlSecSymbianCryptoX509NameStringRead", |
|
1058 XMLSEC_ERRORS_R_XMLSEC_FAILED, |
|
1059 XMLSEC_ERRORS_NO_MESSAGE); |
|
1060 X509_NAME_free(nm); |
|
1061 return(NULL); |
|
1062 } |
|
1063 name[nameLen] = '\0'; |
|
1064 if(len > 0) { |
|
1065 ++str; --len; |
|
1066 if((*str) == '\"') { |
|
1067 ++str; --len; |
|
1068 valueLen = xmlSecSymbianCryptoX509NameStringRead(&str, &len, |
|
1069 value, sizeof(value), '"', 1); |
|
1070 if(valueLen < 0) { |
|
1071 xmlSecError(XMLSEC_ERRORS_HERE, |
|
1072 NULL, |
|
1073 "xmlSecSymbianCryptoX509NameStringRead", |
|
1074 XMLSEC_ERRORS_R_XMLSEC_FAILED, |
|
1075 XMLSEC_ERRORS_NO_MESSAGE); |
|
1076 X509_NAME_free(nm); |
|
1077 return(NULL); |
|
1078 } |
|
1079 |
|
1080 /* skip quote */ |
|
1081 if((len <= 0) || ((*str) != '\"')) { |
|
1082 xmlSecError(XMLSEC_ERRORS_HERE, |
|
1083 NULL, |
|
1084 NULL, |
|
1085 XMLSEC_ERRORS_R_INVALID_DATA, |
|
1086 "quote is expected:%s", |
|
1087 xmlSecErrorsSafeString(str)); |
|
1088 X509_NAME_free(nm); |
|
1089 return(NULL); |
|
1090 } |
|
1091 ++str; --len; |
|
1092 |
|
1093 /* skip spaces before comma or semicolon */ |
|
1094 while((len > 0) && isspace(*str)) { |
|
1095 ++str; --len; |
|
1096 } |
|
1097 if((len > 0) && ((*str) != ',')) { |
|
1098 xmlSecError(XMLSEC_ERRORS_HERE, |
|
1099 NULL, |
|
1100 NULL, |
|
1101 XMLSEC_ERRORS_R_INVALID_DATA, |
|
1102 "comma is expected:%s", |
|
1103 xmlSecErrorsSafeString(str)); |
|
1104 X509_NAME_free(nm); |
|
1105 return(NULL); |
|
1106 } |
|
1107 if(len > 0) { |
|
1108 ++str; --len; |
|
1109 } |
|
1110 type = MBSTRING_ASC; |
|
1111 } else if((*str) == '#') { |
|
1112 /* Not implemented currently */ |
|
1113 xmlSecError(XMLSEC_ERRORS_HERE, |
|
1114 NULL, |
|
1115 NULL, |
|
1116 XMLSEC_ERRORS_R_INVALID_DATA, |
|
1117 "reading octect values is not implemented yet"); |
|
1118 X509_NAME_free(nm); |
|
1119 return(NULL); |
|
1120 } else { |
|
1121 valueLen = xmlSecSymbianCryptoX509NameStringRead(&str, &len, |
|
1122 value, sizeof(value), ',', 1); |
|
1123 if(valueLen < 0) { |
|
1124 xmlSecError(XMLSEC_ERRORS_HERE, |
|
1125 NULL, |
|
1126 "xmlSecSymbianCryptoX509NameStringRead", |
|
1127 XMLSEC_ERRORS_R_XMLSEC_FAILED, |
|
1128 XMLSEC_ERRORS_NO_MESSAGE); |
|
1129 X509_NAME_free(nm); |
|
1130 return(NULL); |
|
1131 } |
|
1132 type = MBSTRING_ASC; |
|
1133 } |
|
1134 } else { |
|
1135 valueLen = 0; |
|
1136 } |
|
1137 value[valueLen] = '\0'; |
|
1138 if(len > 0) { |
|
1139 ++str; --len; |
|
1140 } |
|
1141 X509_NAME_add_entry_by_txt(nm, (char*)name, type, value, valueLen, -1, 0); |
|
1142 } |
|
1143 #endif //XMLSEC_FUTURE_SUPPORT |
|
1144 return(nm); |
|
1145 } |
|
1146 |
|
1147 |
|
1148 |
|
1149 /** |
|
1150 * xmlSecSymbianCryptoX509NameStringRead: |
|
1151 */ |
|
1152 static int |
|
1153 xmlSecSymbianCryptoX509NameStringRead(xmlSecByte **str, int *strLen, |
|
1154 xmlSecByte *res, int resLen, |
|
1155 xmlSecByte delim, int ingoreTrailingSpaces) { |
|
1156 xmlSecByte *p, *q, *nonSpace; |
|
1157 |
|
1158 xmlSecAssert2(str, -1); |
|
1159 xmlSecAssert2(strLen, -1); |
|
1160 xmlSecAssert2(res, -1); |
|
1161 |
|
1162 p = (*str); |
|
1163 nonSpace = q = res; |
|
1164 while(((p - (*str)) < (*strLen)) && ((*p) != delim) && ((q - res) < resLen)) { |
|
1165 if((*p) != '\\') { |
|
1166 if(ingoreTrailingSpaces && !isspace(*p)) nonSpace = q; |
|
1167 *(q++) = *(p++); |
|
1168 } else { |
|
1169 ++p; |
|
1170 nonSpace = q; |
|
1171 if(xmlSecIsHex((*p))) { |
|
1172 if((p - (*str) + 1) >= (*strLen)) { |
|
1173 xmlSecError(XMLSEC_ERRORS_HERE, |
|
1174 NULL, |
|
1175 NULL, |
|
1176 XMLSEC_ERRORS_R_INVALID_DATA, |
|
1177 "two hex digits expected"); |
|
1178 return(-1); |
|
1179 } |
|
1180 *(q++) = xmlSecGetHex(p[0]) * 16 + xmlSecGetHex(p[1]); |
|
1181 p += 2; |
|
1182 } else { |
|
1183 if(((++p) - (*str)) >= (*strLen)) { |
|
1184 xmlSecError(XMLSEC_ERRORS_HERE, |
|
1185 NULL, |
|
1186 NULL, |
|
1187 XMLSEC_ERRORS_R_INVALID_DATA, |
|
1188 "escaped symbol missed"); |
|
1189 return(-1); |
|
1190 } |
|
1191 *(q++) = *(p++); |
|
1192 } |
|
1193 } |
|
1194 } |
|
1195 if(((p - (*str)) < (*strLen)) && ((*p) != delim)) { |
|
1196 xmlSecError(XMLSEC_ERRORS_HERE, |
|
1197 NULL, |
|
1198 NULL, |
|
1199 XMLSEC_ERRORS_R_INVALID_SIZE, |
|
1200 "buffer is too small"); |
|
1201 return(-1); |
|
1202 } |
|
1203 (*strLen) -= (p - (*str)); |
|
1204 (*str) = p; |
|
1205 return((ingoreTrailingSpaces) ? nonSpace - res + 1 : q - res); |
|
1206 } |
|
1207 |
|
1208 static |
|
1209 int xmlSecSymbianCryptoX509_NAME_cmp(const X509_NAME *a, const X509_NAME *b) { |
|
1210 int i,ret; |
|
1211 /* |
|
1212 const X509_NAME_ENTRY *na,*nb; |
|
1213 |
|
1214 xmlSecAssert2(a != NULL, -1); |
|
1215 xmlSecAssert2(b != NULL, 1); |
|
1216 |
|
1217 if (sk_X509_NAME_ENTRY_num(a->entries) != sk_X509_NAME_ENTRY_num(b->entries)) { |
|
1218 return sk_X509_NAME_ENTRY_num(a->entries) - sk_X509_NAME_ENTRY_num(b->entries); |
|
1219 } |
|
1220 |
|
1221 for (i=sk_X509_NAME_ENTRY_num(a->entries)-1; i>=0; i--) { |
|
1222 na=sk_X509_NAME_ENTRY_value(a->entries,i); |
|
1223 nb=sk_X509_NAME_ENTRY_value(b->entries,i); |
|
1224 |
|
1225 ret = xmlSecSymbianCryptoX509_NAME_ENTRY_cmp(&na, &nb); |
|
1226 if(ret != 0) { |
|
1227 return(ret); |
|
1228 } |
|
1229 } |
|
1230 */ |
|
1231 return(0); |
|
1232 } |
|
1233 |
|
1234 |
|
1235 /** |
|
1236 * xmlSecSymbianCryptoX509NamesCompare: |
|
1237 * |
|
1238 * we have to sort X509_NAME entries to get correct results. |
|
1239 * This is ugly but SymbianCrypto does not support it |
|
1240 */ |
|
1241 static int |
|
1242 xmlSecSymbianCryptoX509NamesCompare(X509_NAME *a, X509_NAME *b) { |
|
1243 X509_NAME *a1 = NULL; |
|
1244 X509_NAME *b1 = NULL; |
|
1245 int ret = -1; |
|
1246 |
|
1247 xmlSecAssert2(a, -1); |
|
1248 xmlSecAssert2(b, 1); |
|
1249 #ifdef XMLSEC_FUTURE_SUPPORT |
|
1250 a1 = X509_NAME_dup(a); |
|
1251 if(!a1) { |
|
1252 xmlSecError(XMLSEC_ERRORS_HERE, |
|
1253 NULL, |
|
1254 "X509_NAME_dup", |
|
1255 XMLSEC_ERRORS_R_CRYPTO_FAILED, |
|
1256 XMLSEC_ERRORS_NO_MESSAGE); |
|
1257 return(-1); |
|
1258 } |
|
1259 b1 = X509_NAME_dup(b); |
|
1260 if(!b1) { |
|
1261 xmlSecError(XMLSEC_ERRORS_HERE, |
|
1262 NULL, |
|
1263 "X509_NAME_dup", |
|
1264 XMLSEC_ERRORS_R_CRYPTO_FAILED, |
|
1265 XMLSEC_ERRORS_NO_MESSAGE); |
|
1266 return(1); |
|
1267 } |
|
1268 |
|
1269 /* sort both */ |
|
1270 sk_X509_NAME_ENTRY_set_cmp_func(a1->entries, xmlSecSymbianCryptoX509_NAME_ENTRY_cmp); |
|
1271 sk_X509_NAME_ENTRY_sort(a1->entries); |
|
1272 sk_X509_NAME_ENTRY_set_cmp_func(b1->entries, xmlSecSymbianCryptoX509_NAME_ENTRY_cmp); |
|
1273 sk_X509_NAME_ENTRY_sort(b1->entries); |
|
1274 |
|
1275 /* actually compare */ |
|
1276 ret = xmlSecSymbianCryptoX509_NAME_cmp(a1, b1); |
|
1277 |
|
1278 /* cleanup */ |
|
1279 X509_NAME_free(a1); |
|
1280 X509_NAME_free(b1); |
|
1281 #endif //XMLSEC_FUTURE_SUPPORT |
|
1282 return(ret); |
|
1283 } |
|
1284 |
|
1285 |
|
1286 /** |
|
1287 * xmlSecSymbianCryptoX509_NAME_ENTRY_cmp: |
|
1288 */ |
|
1289 #ifdef XMLSEC_FUTURE_SUPPORT |
|
1290 static int |
|
1291 xmlSecSymbianCryptoX509_NAME_ENTRY_cmp(const X509_NAME_ENTRY **a, const X509_NAME_ENTRY **b) { |
|
1292 int ret; |
|
1293 |
|
1294 xmlSecAssert2(a, -1); |
|
1295 xmlSecAssert2(b, 1); |
|
1296 xmlSecAssert2((*a), -1); |
|
1297 xmlSecAssert2((*b), 1); |
|
1298 |
|
1299 /* first compare values */ |
|
1300 if((!((*a)->value)) && ((*b)->value)) { |
|
1301 return(-1); |
|
1302 } else if(((*a)->value) && (!((*b)->value))) { |
|
1303 return(1); |
|
1304 } else if((!((*a)->value)) && (!((*b)->value))) { |
|
1305 return(0); |
|
1306 } |
|
1307 |
|
1308 ret = (*a)->value->length - (*b)->value->length; |
|
1309 if(ret != 0) { |
|
1310 return(ret); |
|
1311 } |
|
1312 |
|
1313 ret = memcmp((*a)->value->data, (*b)->value->data, (*a)->value->length); |
|
1314 if(ret != 0) { |
|
1315 return(ret); |
|
1316 } |
|
1317 |
|
1318 /* next compare names */ |
|
1319 return(OBJ_cmp((*a)->object, (*b)->object)); |
|
1320 } |
|
1321 #endif //XMLSEC_FUTURE_SUPPORT |
|
1322 |
|
1323 |
|
1324 #endif /* XMLSEC_NO_X509 */ |
|
1325 |
|
1326 |