xmlsecurityengine/xmlseccrypto/src/xmlsecc_x509vfy.cpp
changeset 0 e35f40988205
child 8 e65204f75c47
equal deleted inserted replaced
-1:000000000000 0:e35f40988205
       
     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