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