--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/xmlsecurityengine/xmlseccrypto/src/xmlsecc_x509vfy.cpp Thu Dec 17 09:29:21 2009 +0200
@@ -0,0 +1,1326 @@
+/**
+ * XMLSec library
+ *
+ * X509 support
+ *
+ *
+ * This is free software; see Copyright file in the source
+ * distribution for preciese wording.
+ *
+ * Copyright (C) 2002-2003 Aleksey Sanin <aleksey@aleksey.com>
+ * Portion Copyright © 2009 Nokia Corporation and/or its subsidiary(-ies). All rights reserved.
+ */
+#include "xmlsecc_config.h"
+#ifndef XMLSEC_NO_X509
+#include "xmlsecc_globals.h"
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <ctype.h>
+#include <errno.h>
+
+#include <libxml2_tree.h>
+
+#include "xmlsec_xmlsec.h"
+#include "xmlsec_xmltree.h"
+#include "xmlsec_keys.h"
+#include "xmlsec_keyinfo.h"
+#include "xmlsec_keysmngr.h"
+#include "xmlsec_base64.h"
+#include "xmlsec_errors.h"
+
+#include "xmlsecc_crypto.h"
+#include "xmlsecc_x509wrapper.h"
+#include "xmlsecc_x509.h"
+#include "xmlsec_error_flag.h"
+
+#define XMLSEC_OPENSSL_097
+
+/**************************************************************************
+ *
+ * Internal SymbianCrypto X509 store CTX
+ *
+ *************************************************************************/
+typedef struct _xmlSecSymbianCryptoX509StoreCtx xmlSecSymbianCryptoX509StoreCtx,
+ *xmlSecSymbianCryptoX509StoreCtxPtr;
+struct _xmlSecSymbianCryptoX509StoreCtx {
+ X509_STORE* xst;
+ STACK_OF(X509)* untrusted;
+ STACK_OF(X509_CRL)* crls;
+
+#if !defined(XMLSEC_OPENSSL_096) && !defined(XMLSEC_OPENSSL_097)
+ X509_VERIFY_PARAM * vpm;
+#endif /* !defined(XMLSEC_OPENSSL_096) && !defined(XMLSEC_OPENSSL_097) */
+};
+
+/****************************************************************************
+ *
+ * xmlSecSymbianCryptoKeyDataStoreX509Id:
+ *
+ * xmlSecSymbianCryptoX509StoreCtx is located after xmlSecTransform
+ *
+ ***************************************************************************/
+#define xmlSecSymbianCryptoX509StoreGetCtx(store) \
+ ((xmlSecSymbianCryptoX509StoreCtxPtr)(((xmlSecByte*)(store)) + \
+ sizeof(xmlSecKeyDataStoreKlass)))
+#define xmlSecSymbianCryptoX509StoreSize \
+ (sizeof(xmlSecKeyDataStoreKlass) + sizeof(xmlSecSymbianCryptoX509StoreCtx))
+
+static int xmlSecSymbianCryptoX509StoreInitialize (xmlSecKeyDataStorePtr store);
+static void xmlSecSymbianCryptoX509StoreFinalize (xmlSecKeyDataStorePtr store);
+
+static xmlSecKeyDataStoreKlass xmlSecSymbianCryptoX509StoreKlass = {
+ sizeof(xmlSecKeyDataStoreKlass),
+ xmlSecSymbianCryptoX509StoreSize,
+
+ /* data */
+ xmlSecNameX509Store, /* const xmlChar* name; */
+
+ /* constructors/destructor */
+ xmlSecSymbianCryptoX509StoreInitialize, /* xmlSecKeyDataStoreInitializeMethod initialize; */
+ xmlSecSymbianCryptoX509StoreFinalize, /* xmlSecKeyDataStoreFinalizeMethod finalize; */
+
+ /* reserved for the future */
+ NULL, /* void* reserved0; */
+ NULL, /* void* reserved1; */
+};
+
+static int xmlSecSymbianCryptoX509VerifyCrl (X509_STORE* xst,
+ X509_CRL *crl );
+static X509* xmlSecSymbianCryptoX509FindCert (STACK_OF(X509) *certs,
+ xmlChar *subjectName,
+ xmlChar *issuerName,
+ xmlChar *issuerSerial,
+ xmlChar *ski);
+static X509* xmlSecSymbianCryptoX509FindNextChainCert (STACK_OF(X509) *chain,
+ X509 *cert);
+static int xmlSecSymbianCryptoX509VerifyCertAgainstCrls (STACK_OF(X509_CRL) *crls,
+ X509* cert);
+static X509_NAME* xmlSecSymbianCryptoX509NameRead (xmlSecByte *str,
+ int len);
+static int xmlSecSymbianCryptoX509NameStringRead (xmlSecByte **str,
+ int *strLen,
+ xmlSecByte *res,
+ int resLen,
+ xmlSecByte delim,
+ int ingoreTrailingSpaces);
+static int xmlSecSymbianCryptoX509NamesCompare (X509_NAME *a,
+ X509_NAME *b);
+static int xmlSecSymbianCryptoX509_NAME_cmp (const X509_NAME *a,
+ const X509_NAME *b);
+/*
+static int xmlSecSymbianCryptoX509_NAME_ENTRY_cmp (const X509_NAME_ENTRY **a,
+ const X509_NAME_ENTRY **b);
+*/
+/**
+ * xmlSecSymbianCryptoX509StoreGetKlass:
+ *
+ * The SymbianCrypto X509 certificates key data store klass.
+ *
+ * Returns pointer to SymbianCrypto X509 certificates key data store klass.
+ */
+EXPORT_C
+xmlSecKeyDataStoreId
+xmlSecSymbianCryptoX509StoreGetKlass(void) {
+ return(&xmlSecSymbianCryptoX509StoreKlass);
+}
+
+/**
+ * xmlSecSymbianCryptoX509StoreFindCert:
+ * @store: the pointer to X509 key data store klass.
+ * @subjectName: the desired certificate name.
+ * @issuerName: the desired certificate issuer name.
+ * @issuerSerial: the desired certificate issuer serial number.
+ * @ski: the desired certificate SKI.
+ * @keyInfoCtx: the pointer to <dsig:KeyInfo/> element processing context.
+ *
+ * Searches @store for a certificate that matches given criteria.
+ *
+ * Returns pointer to found certificate or NULL if certificate is not found
+ * or an error occurs.
+ */
+EXPORT_C
+X509*
+xmlSecSymbianCryptoX509StoreFindCert(xmlSecKeyDataStorePtr store, xmlChar *subjectName,
+ xmlChar *issuerName, xmlChar *issuerSerial,
+ xmlChar *ski, xmlSecKeyInfoCtx* keyInfoCtx) {
+ xmlSecSymbianCryptoX509StoreCtxPtr ctx;
+ X509* res = NULL;
+
+ xmlSecAssert2(xmlSecKeyDataStoreCheckId(store, xmlSecSymbianCryptoX509StoreId), NULL);
+ xmlSecAssert2(keyInfoCtx, NULL);
+
+ ctx = xmlSecSymbianCryptoX509StoreGetCtx(store);
+ xmlSecAssert2(ctx, NULL);
+
+ if((!res) && (ctx->untrusted)) {
+ res = xmlSecSymbianCryptoX509FindCert(ctx->untrusted,
+ subjectName,
+ issuerName,
+ issuerSerial,
+ ski);
+ }
+ return(res);
+}
+
+
+/**
+ * xmlSecSymbianCryptoX509StoreVerify:
+ * @store: the pointer to X509 key data store klass.
+ * @cert: the untrusted key cert.
+ *
+ * Verifies @certs list.
+ *
+ * Returns Result of the verification
+ */
+EXPORT_C
+int
+xmlSecSymbianCryptoX509StoreKeyCertVerify(xmlSecKeyDataStorePtr store, X509* cert) {
+ xmlSecSymbianCryptoX509StoreCtxPtr ctx;
+ X509* res = NULL;
+ X509 *err_cert = NULL;
+ char buf[256];
+ int err = 0, depth;
+ int i;
+ int ret;
+
+ xmlSecAssert2(xmlSecKeyDataStoreCheckId(store, xmlSecSymbianCryptoX509StoreId), NULL);
+ xmlSecAssert2(cert, NULL);
+
+ ctx = xmlSecSymbianCryptoX509StoreGetCtx(store);
+ xmlSecAssert2(ctx, NULL);
+ xmlSecAssert2(ctx->xst, NULL);
+
+ if(!xmlSecCheckCertStoreFlag()) //SymbianCertStore Flag == FALSE
+ {
+ err = X509_STORE_certchain_init (ctx->xst, cert);
+ if(err != 0) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ xmlSecErrorsSafeString(xmlSecKeyDataStoreGetName(store)),
+ "X509_STORE_certchain_init",
+ XMLSEC_ERRORS_R_CRYPTO_FAILED,
+ XMLSEC_ERRORS_NO_MESSAGE);
+ //goto done;
+ return -1;
+ }
+ err = X509_STORE_certchain_validate(ctx->xst);
+ if(err != 0) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ xmlSecErrorsSafeString(xmlSecKeyDataStoreGetName(store)),
+ "X509_STORE_certchain_init",
+ XMLSEC_ERRORS_R_CRYPTO_FAILED,
+ XMLSEC_ERRORS_NO_MESSAGE);
+ //goto done;
+ return -1;
+ }
+
+ return X509_STORE_certchain_getValidateResult(ctx->xst);
+ }
+else //SymbianCertStore Flag ==TRUE
+ {
+ err = X509_STORE_certchain_init_fromCertStore(ctx->xst, cert);
+ if(err != 0) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ xmlSecErrorsSafeString(xmlSecKeyDataStoreGetName(store)),
+ "X509_STORE_certchain_init",
+ XMLSEC_ERRORS_R_CRYPTO_FAILED,
+ XMLSEC_ERRORS_NO_MESSAGE);
+ //goto done;
+ return -1;
+ }
+ err = X509_STORE_certchain_validate(ctx->xst);
+ if(err != 0) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ xmlSecErrorsSafeString(xmlSecKeyDataStoreGetName(store)),
+ "X509_STORE_certchain_init",
+ XMLSEC_ERRORS_R_CRYPTO_FAILED,
+ XMLSEC_ERRORS_NO_MESSAGE);
+ //goto done;
+ return -1;
+ }
+ return X509_STORE_certchain_getValidateResult(ctx->xst);
+ } //else
+}
+
+/**
+ * xmlSecSymbianCryptoX509StoreVerify:
+ * @store: the pointer to X509 key data store klass.
+ * @certs: the untrusted certificates stack.
+ * @crls: the crls stack.
+ * @keyInfoCtx: the pointer to <dsig:KeyInfo/> element processing context.
+ *
+ * Verifies @certs list.
+ *
+ * Returns pointer to the first verified certificate from @certs.
+ */
+EXPORT_C
+X509*
+xmlSecSymbianCryptoX509StoreVerify(xmlSecKeyDataStorePtr store, XMLSEC_STACK_OF_X509* certs,
+ XMLSEC_STACK_OF_X509_CRL* crls, xmlSecKeyInfoCtx* keyInfoCtx) {
+ xmlSecSymbianCryptoX509StoreCtxPtr ctx;
+ STACK_OF(X509)* certs2 = NULL;
+ X509* res = NULL;
+ X509* cert = NULL;
+ X509 *err_cert = NULL;
+ char buf[256];
+ int err = 0, depth;
+ int i;
+ int ret;
+
+ xmlSecAssert2(xmlSecKeyDataStoreCheckId(store, xmlSecSymbianCryptoX509StoreId), NULL);
+ xmlSecAssert2(certs, NULL);
+ xmlSecAssert2(keyInfoCtx, NULL);
+
+ ctx = xmlSecSymbianCryptoX509StoreGetCtx(store);
+ xmlSecAssert2(ctx, NULL);
+ xmlSecAssert2(ctx->xst, NULL);
+
+ err = X509_STORE_certchain_init (ctx->xst, certs);
+ if(err != 0) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ xmlSecErrorsSafeString(xmlSecKeyDataStoreGetName(store)),
+ "X509_STORE_certchain_init",
+ XMLSEC_ERRORS_R_CRYPTO_FAILED,
+ XMLSEC_ERRORS_NO_MESSAGE);
+ }
+
+
+ err = X509_STORE_certchain_validate(ctx->xst);
+ if(err != 0) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ xmlSecErrorsSafeString(xmlSecKeyDataStoreGetName(store)),
+ "X509_STORE_certchain_init",
+ XMLSEC_ERRORS_R_CRYPTO_FAILED,
+ XMLSEC_ERRORS_NO_MESSAGE);
+ }
+
+ ret = X509_STORE_certchain_getValidateResult(ctx->xst);
+ if(ret == 1) {
+ res = cert;
+ }
+
+#ifdef XMLSEC_FUTURE_SUPPORT
+ /* dup certs */
+ /*
+ certs2 = sk_X509_dup(certs);
+ if(certs2 == NULL) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ xmlSecErrorsSafeString(xmlSecKeyDataStoreGetName(store)),
+ "sk_X509_dup",
+ XMLSEC_ERRORS_R_CRYPTO_FAILED,
+ XMLSEC_ERRORS_NO_MESSAGE);
+ goto done;
+ }
+ */
+ /* add untrusted certs from the store */
+#ifndef XMLSEC_NO_X509_UNTRUST
+ if(ctx->untrusted) {
+ for(i = 0; i < sk_X509_num(ctx->untrusted); ++i) {
+ ret = sk_X509_push(certs2, sk_X509_value(ctx->untrusted, i));
+ if(ret < 1) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ xmlSecErrorsSafeString(xmlSecKeyDataStoreGetName(store)),
+ "sk_X509_push",
+ XMLSEC_ERRORS_R_CRYPTO_FAILED,
+ XMLSEC_ERRORS_NO_MESSAGE);
+ goto done;
+ }
+ }
+ }
+#endif //XMLSEC_NO_X509_UNTRUST
+
+#ifndef XMLSEC_NO_X509_CRL
+ /* dup crls but remove all non-verified */
+ if(crls) {
+ crls2 = sk_X509_CRL_dup(crls);
+ if(!crls2) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ xmlSecErrorsSafeString(xmlSecKeyDataStoreGetName(store)),
+ "sk_X509_CRL_dup",
+ XMLSEC_ERRORS_R_CRYPTO_FAILED,
+ XMLSEC_ERRORS_NO_MESSAGE);
+ goto done;
+ }
+
+ for(i = 0; i < sk_X509_CRL_num(crls2); ) {
+ ret = xmlSecSymbianCryptoX509VerifyCrl(ctx->xst, sk_X509_CRL_value(crls2, i));
+ if(ret == 1) {
+ ++i;
+ } else if(ret == 0) {
+ sk_X509_CRL_delete(crls2, i);
+ } else {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ xmlSecErrorsSafeString(xmlSecKeyDataStoreGetName(store)),
+ "xmlSecSymbianCryptoX509VerifyCrl",
+ XMLSEC_ERRORS_R_XMLSEC_FAILED,
+ XMLSEC_ERRORS_NO_MESSAGE);
+ goto done;
+ }
+ }
+ }
+
+ /* remove all revoked certs */
+ for(i = 0; i < sk_X509_num(certs2);) {
+ cert = sk_X509_value(certs2, i);
+
+ if(crls2) {
+ ret = xmlSecSymbianCryptoX509VerifyCertAgainstCrls(crls2, cert);
+ if(ret == 0) {
+ sk_X509_delete(certs2, i);
+ continue;
+ } else if(ret != 1) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ xmlSecErrorsSafeString(xmlSecKeyDataStoreGetName(store)),
+ "xmlSecSymbianCryptoX509VerifyCertAgainstCrls",
+ XMLSEC_ERRORS_R_XMLSEC_FAILED,
+ XMLSEC_ERRORS_NO_MESSAGE);
+ goto done;
+ }
+ }
+
+ if(ctx->crls) {
+ ret = xmlSecSymbianCryptoX509VerifyCertAgainstCrls(ctx->crls, cert);
+ if(ret == 0) {
+ sk_X509_delete(certs2, i);
+ continue;
+ } else if(ret != 1) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ xmlSecErrorsSafeString(xmlSecKeyDataStoreGetName(store)),
+ "xmlSecSymbianCryptoX509VerifyCertAgainstCrls",
+ XMLSEC_ERRORS_R_XMLSEC_FAILED,
+ XMLSEC_ERRORS_NO_MESSAGE);
+ goto done;
+ }
+ }
+ ++i;
+ }
+
+#endif //XMLSEC_NO_X509_CRL
+
+ /* get one cert after another and try to verify */
+ for(i = 0; i < sk_X509_num(certs2); ++i) {
+ cert = sk_X509_value(certs2, i);
+ if(!xmlSecSymbianCryptoX509FindNextChainCert(certs2, cert)) {
+ X509_STORE_CTX xsc;
+
+#if !defined(XMLSEC_OPENSSL_096) && !defined(XMLSEC_OPENSSL_097)
+ X509_VERIFY_PARAM * vpm = NULL;
+ unsigned long vpm_flags = 0;
+
+ vpm = X509_VERIFY_PARAM_new();
+ if(!vpm) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ xmlSecErrorsSafeString(xmlSecKeyDataStoreGetName(store)),
+ "X509_VERIFY_PARAM_new",
+ XMLSEC_ERRORS_R_CRYPTO_FAILED,
+ XMLSEC_ERRORS_NO_MESSAGE);
+ goto done;
+ }
+ vpm_flags = vpm->flags;
+/*
+ vpm_flags &= (~X509_V_FLAG_X509_STRICT);
+*/
+ vpm_flags &= (~X509_V_FLAG_CRL_CHECK);
+
+ X509_VERIFY_PARAM_set_depth(vpm, 9);
+ X509_VERIFY_PARAM_set_flags(vpm, vpm_flags);
+#endif /* !defined(XMLSEC_OPENSSL_096) && !defined(XMLSEC_OPENSSL_097) */
+
+
+ X509_STORE_CTX_init (&xsc, ctx->xst, cert, certs2);
+
+ if(keyInfoCtx->certsVerificationTime > 0) {
+#if !defined(XMLSEC_OPENSSL_096) && !defined(XMLSEC_OPENSSL_097)
+ vpm_flags |= X509_V_FLAG_USE_CHECK_TIME;
+ X509_VERIFY_PARAM_set_time(vpm, keyInfoCtx->certsVerificationTime);
+#endif /* !defined(XMLSEC_OPENSSL_096) && !defined(XMLSEC_OPENSSL_097) */
+ X509_STORE_CTX_set_time(&xsc, 0, keyInfoCtx->certsVerificationTime);
+ }
+
+#if !defined(XMLSEC_OPENSSL_096) && !defined(XMLSEC_OPENSSL_097)
+ X509_STORE_CTX_set0_param(&xsc, vpm);
+#endif /* !defined(XMLSEC_OPENSSL_096) && !defined(XMLSEC_OPENSSL_097) */
+
+
+ ret = X509_verify_cert(&xsc);
+ err_cert = X509_STORE_CTX_get_current_cert(&xsc);
+ err = X509_STORE_CTX_get_error(&xsc);
+ depth = X509_STORE_CTX_get_error_depth(&xsc);
+
+ X509_STORE_CTX_cleanup (&xsc);
+
+ if(ret == 1) {
+ res = cert;
+ goto done;
+ } else if(ret < 0) {
+ const char* err_msg;
+
+ buf[0] = '\0';
+ X509_NAME_oneline(X509_get_subject_name(err_cert), buf, sizeof buf);
+ err_msg = X509_verify_cert_error_string(err);
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ xmlSecErrorsSafeString(xmlSecKeyDataStoreGetName(store)),
+ "X509_verify_cert",
+ XMLSEC_ERRORS_R_CRYPTO_FAILED,
+ "subj=%s;err=%d;msg=%s",
+ xmlSecErrorsSafeString(buf),
+ err,
+ xmlSecErrorsSafeString(err_msg));
+ goto done;
+ } else if(ret == 0) {
+ const char* err_msg;
+
+ buf[0] = '\0';
+ X509_NAME_oneline(X509_get_subject_name(err_cert), buf, sizeof buf);
+ err_msg = X509_verify_cert_error_string(err);
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ xmlSecErrorsSafeString(xmlSecKeyDataStoreGetName(store)),
+ "X509_verify_cert",
+ XMLSEC_ERRORS_R_CRYPTO_FAILED,
+ "subj=%s;err=%d;msg=%s",
+ xmlSecErrorsSafeString(buf),
+ err,
+ xmlSecErrorsSafeString(err_msg));
+ }
+ }
+ }
+
+ /* if we came here then we found nothing. do we have any error? */
+ if((err != 0) && (err_cert)) {
+ const char* err_msg;
+
+ err_msg = X509_verify_cert_error_string(err);
+ switch (err) {
+ case X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT:
+ X509_NAME_oneline(X509_get_issuer_name(err_cert), buf, sizeof buf);
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ xmlSecErrorsSafeString(xmlSecKeyDataStoreGetName(store)),
+ NULL,
+ XMLSEC_ERRORS_R_CERT_ISSUER_FAILED,
+ "err=%d;msg=%s;issuer=%s",
+ err,
+ xmlSecErrorsSafeString(err_msg),
+ xmlSecErrorsSafeString(buf));
+ break;
+ case X509_V_ERR_CERT_NOT_YET_VALID:
+ case X509_V_ERR_ERROR_IN_CERT_NOT_BEFORE_FIELD:
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ xmlSecErrorsSafeString(xmlSecKeyDataStoreGetName(store)),
+ NULL,
+ XMLSEC_ERRORS_R_CERT_NOT_YET_VALID,
+ "err=%d;msg=%s", err,
+ xmlSecErrorsSafeString(err_msg));
+ break;
+ case X509_V_ERR_CERT_HAS_EXPIRED:
+ case X509_V_ERR_ERROR_IN_CERT_NOT_AFTER_FIELD:
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ xmlSecErrorsSafeString(xmlSecKeyDataStoreGetName(store)),
+ NULL,
+ XMLSEC_ERRORS_R_CERT_HAS_EXPIRED,
+ "err=%d;msg=%s", err,
+ xmlSecErrorsSafeString(err_msg));
+ break;
+ default:
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ xmlSecErrorsSafeString(xmlSecKeyDataStoreGetName(store)),
+ NULL,
+ XMLSEC_ERRORS_R_CERT_VERIFY_FAILED,
+ "err=%d;msg=%s", err,
+ xmlSecErrorsSafeString(err_msg));
+ }
+ }
+
+done:
+
+ if(certs2) {
+ X509_free(certs2);
+ }
+ if(crls2) {
+ sk_X509_CRL_free(crls2);
+ }
+
+#endif //XMLSEC_FUTURE_SUPPORT
+ return(res);
+}
+
+/**
+ * xmlSecSymbianCryptoX509StoreAdoptCert:
+ * @store: the pointer to X509 key data store klass.
+ * @cert: the pointer to SymbianCrypto X509 certificate.
+ * @type: the certificate type (trusted/untrusted).
+ *
+ * Adds trusted (root) or untrusted certificate to the store.
+ *
+ * Returns 0 on success or a negative value if an error occurs.
+ */
+EXPORT_C
+int
+xmlSecSymbianCryptoX509StoreAdoptCert(xmlSecKeyDataStorePtr store,
+ X509* cert,
+ xmlSecKeyDataType type) {
+ xmlSecSymbianCryptoX509StoreCtxPtr ctx;
+ int ret = -1;
+
+ xmlSecAssert2(xmlSecKeyDataStoreCheckId(store, xmlSecSymbianCryptoX509StoreId), -1);
+ xmlSecAssert2(cert, -1);
+
+ ctx = xmlSecSymbianCryptoX509StoreGetCtx(store);
+ xmlSecAssert2(ctx, -1);
+
+ if((type & xmlSecKeyDataTypeTrusted) != 0) {
+ xmlSecAssert2(ctx->xst, -1);
+
+ ret = X509_STORE_add_cert(ctx->xst, cert);
+ if(ret != 0) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ xmlSecErrorsSafeString(xmlSecKeyDataStoreGetName(store)),
+ "X509_STORE_add_cert",
+ XMLSEC_ERRORS_R_CRYPTO_FAILED,
+ XMLSEC_ERRORS_NO_MESSAGE);
+ xmlSecSetErrorFlag( ret );
+ return(-1);
+ }
+ /* add cert increments the reference */
+ X509_free(cert);
+ } else {
+ xmlSecAssert2(ctx->untrusted, -1);
+
+ if(ret < 1) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ xmlSecErrorsSafeString(xmlSecKeyDataStoreGetName(store)),
+ "sk_X509_push",
+ XMLSEC_ERRORS_R_CRYPTO_FAILED,
+ XMLSEC_ERRORS_NO_MESSAGE);
+ return(-1);
+ }
+ }
+ return(0);
+}
+
+/**
+ * xmlSecSymbianCryptoX509StoreAddCertsPath:
+ * @store: the pointer to SymbianCrypto x509 store.
+ * @path: the path to the certs dir.
+ *
+ * Adds all certs in the @path to the list of trusted certs
+ * in @store.
+ *
+ * Returns 0 on success or a negative value otherwise.
+ */
+EXPORT_C
+int
+xmlSecSymbianCryptoX509StoreAddCertsPath(xmlSecKeyDataStorePtr store, const char *path) {
+ xmlSecSymbianCryptoX509StoreCtxPtr ctx;
+
+ xmlSecAssert2(xmlSecKeyDataStoreCheckId(store, xmlSecSymbianCryptoX509StoreId), -1);
+ xmlSecAssert2(path, -1);
+
+ ctx = xmlSecSymbianCryptoX509StoreGetCtx(store);
+ xmlSecAssert2(ctx, -1);
+ xmlSecAssert2(ctx->xst, -1);
+ /*
+ lookup = X509_STORE_add_lookup(ctx->xst, X509_LOOKUP_hash_dir());
+ if(lookup == NULL) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ xmlSecErrorsSafeString(xmlSecKeyDataStoreGetName(store)),
+ "X509_STORE_add_lookup",
+ XMLSEC_ERRORS_R_CRYPTO_FAILED,
+ XMLSEC_ERRORS_NO_MESSAGE);
+ return(-1);
+ }
+ X509_LOOKUP_add_dir(lookup, path, X509_FILETYPE_DEFAULT);
+ */
+ return(0);
+}
+
+static int
+xmlSecSymbianCryptoX509StoreInitialize(xmlSecKeyDataStorePtr store) {
+ const xmlChar* path;
+
+ xmlSecSymbianCryptoX509StoreCtxPtr ctx;
+ xmlSecAssert2(xmlSecKeyDataStoreCheckId(store, xmlSecSymbianCryptoX509StoreId), -1);
+
+ ctx = xmlSecSymbianCryptoX509StoreGetCtx(store);
+ xmlSecAssert2(ctx, -1);
+
+ memset(ctx, 0, sizeof(xmlSecSymbianCryptoX509StoreCtx));
+
+ ctx->xst = X509_STORE_new();
+ if(!ctx->xst) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ xmlSecErrorsSafeString(xmlSecKeyDataStoreGetName(store)),
+ "X509_STORE_new",
+ XMLSEC_ERRORS_R_CRYPTO_FAILED,
+ XMLSEC_ERRORS_NO_MESSAGE);
+ return(-1);
+ }
+#ifdef XMLSEC_FUTURE_SUPPORT
+ if(!X509_STORE_set_default_paths(ctx->xst)) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ xmlSecErrorsSafeString(xmlSecKeyDataStoreGetName(store)),
+ "X509_STORE_set_default_paths",
+ XMLSEC_ERRORS_R_CRYPTO_FAILED,
+ XMLSEC_ERRORS_NO_MESSAGE);
+ return(-1);
+ }
+
+ path = xmlSecSymbianCryptoGetDefaultTrustedCertsFolder();
+ if(path) {
+ X509_LOOKUP *lookup = NULL;
+
+ lookup = X509_STORE_add_lookup(ctx->xst, X509_LOOKUP_hash_dir());
+ if(!lookup) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ xmlSecErrorsSafeString(xmlSecKeyDataStoreGetName(store)),
+ "X509_STORE_add_lookup",
+ XMLSEC_ERRORS_R_CRYPTO_FAILED,
+ XMLSEC_ERRORS_NO_MESSAGE);
+ return(-1);
+ }
+ X509_LOOKUP_add_dir(lookup, (char*)path, X509_FILETYPE_DEFAULT);
+ }
+
+ ctx->untrusted = sk_X509_new_null();
+ if(!ctx->untrusted) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ xmlSecErrorsSafeString(xmlSecKeyDataStoreGetName(store)),
+ "sk_X509_new_null",
+ XMLSEC_ERRORS_R_CRYPTO_FAILED,
+ XMLSEC_ERRORS_NO_MESSAGE);
+ return(-1);
+ }
+
+ ctx->crls = sk_X509_CRL_new_null();
+ if(!ctx->crls) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ xmlSecErrorsSafeString(xmlSecKeyDataStoreGetName(store)),
+ "sk_X509_CRL_new_null",
+ XMLSEC_ERRORS_R_CRYPTO_FAILED,
+ XMLSEC_ERRORS_NO_MESSAGE);
+ return(-1);
+ }
+
+#if !defined(XMLSEC_OPENSSL_096) && !defined(XMLSEC_OPENSSL_097)
+ ctx->vpm = X509_VERIFY_PARAM_new();
+ if(!ctx->vpm) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ xmlSecErrorsSafeString(xmlSecKeyDataStoreGetName(store)),
+ "X509_VERIFY_PARAM_new",
+ XMLSEC_ERRORS_R_CRYPTO_FAILED,
+ XMLSEC_ERRORS_NO_MESSAGE);
+ return(-1);
+ }
+ X509_VERIFY_PARAM_set_depth(ctx->vpm, 9); /* the default cert verification path in openssl */
+ X509_STORE_set1_param(ctx->xst, ctx->vpm);
+
+#else /* !defined(XMLSEC_OPENSSL_096) && !defined(XMLSEC_OPENSSL_097) */
+ ctx->xst->depth = 9; /* the default cert verification path in openssl */
+#endif /* !defined(XMLSEC_OPENSSL_096) && !defined(XMLSEC_OPENSSL_097) */
+
+#endif //XMLSEC_FUTURE_SUPPORT
+ return(0);
+}
+
+static void
+xmlSecSymbianCryptoX509StoreFinalize(xmlSecKeyDataStorePtr store) {
+ xmlSecSymbianCryptoX509StoreCtxPtr ctx;
+ xmlSecAssert(xmlSecKeyDataStoreCheckId(store, xmlSecSymbianCryptoX509StoreId));
+
+ ctx = xmlSecSymbianCryptoX509StoreGetCtx(store);
+ xmlSecAssert(ctx);
+
+ if(ctx->xst) {
+ X509_STORE_free(ctx->xst);
+ }
+ if(ctx->untrusted) {
+ }
+ if(ctx->crls) {
+ }
+#if !defined(XMLSEC_OPENSSL_096) && !defined(XMLSEC_OPENSSL_097)
+ if(ctx->vpm) {
+ X509_VERIFY_PARAM_free(ctx->vpm);
+ }
+#endif /* !defined(XMLSEC_OPENSSL_096) && !defined(XMLSEC_OPENSSL_097) */
+ memset(ctx, 0, sizeof(xmlSecSymbianCryptoX509StoreCtx));
+}
+
+
+/*****************************************************************************
+ *
+ * Low-level x509 functions
+ *
+ *****************************************************************************/
+static int
+xmlSecSymbianCryptoX509VerifyCrl(X509_STORE* xst, X509_CRL *crl ) {
+
+ EVP_PKEY *pkey;
+ int ret = 0;
+#ifdef XMLSEC_FUTURE_SUPPORT
+ xmlSecAssert2(xst, -1);
+ xmlSecAssert2(crl, -1);
+
+ X509_STORE_CTX_init(&xsc, xst, NULL, NULL);
+ ret = X509_STORE_get_by_subject(&xsc, X509_LU_X509,
+ X509_CRL_get_issuer(crl), &xobj);
+ if(ret <= 0) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ NULL,
+ "X509_STORE_get_by_subject",
+ XMLSEC_ERRORS_R_CRYPTO_FAILED,
+ XMLSEC_ERRORS_NO_MESSAGE);
+ return(-1);
+ }
+ pkey = X509_get_pubkey(xobj.data.x509);
+ X509_OBJECT_free_contents(&xobj);
+ if(!pkey) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ NULL,
+ "X509_get_pubkey",
+ XMLSEC_ERRORS_R_CRYPTO_FAILED,
+ XMLSEC_ERRORS_NO_MESSAGE);
+ return(-1);
+ }
+ ret = X509_CRL_verify(crl, pkey);
+ EVP_PKEY_free(pkey);
+ if(ret != 1) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ NULL,
+ "X509_CRL_verify",
+ XMLSEC_ERRORS_R_CRYPTO_FAILED,
+ XMLSEC_ERRORS_NO_MESSAGE);
+ }
+ X509_STORE_CTX_cleanup (&xsc);
+#endif //XMLSEC_FUTURE_SUPPORT
+ return((ret == 1) ? 1 : 0);
+}
+
+/**
+ * xmlSecSymbianCryptoX509FindCert:
+ */
+static X509*
+xmlSecSymbianCryptoX509FindCert(STACK_OF(X509) *certs, xmlChar *subjectName,
+ xmlChar *issuerName, xmlChar *issuerSerial,
+ xmlChar *ski) {
+ X509 *cert = NULL;
+ int i;
+
+ xmlSecAssert2(certs, NULL);
+#ifdef XMLSEC_FUTURE_SUPPORT
+ /* may be this is not the fastest way to search certs */
+ if(subjectName) {
+ X509_NAME *nm;
+ X509_NAME *subj;
+
+ nm = xmlSecSymbianCryptoX509NameRead(subjectName, xmlStrlen(subjectName));
+ if(!nm) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ NULL,
+ "xmlSecSymbianCryptoX509NameRead",
+ XMLSEC_ERRORS_R_XMLSEC_FAILED,
+ "subject=%s",
+ xmlSecErrorsSafeString(subjectName));
+ return(NULL);
+ }
+
+ for(i = 0; i < certs->num; ++i) {
+ cert = ((X509**)(certs->data))[i];
+ subj = X509_get_subject_name(cert);
+ if(xmlSecSymbianCryptoX509NamesCompare(nm, subj) == 0) {
+ X509_NAME_free(nm);
+ return(cert);
+ }
+ }
+ X509_NAME_free(nm);
+ } else if((issuerName) && (issuerSerial)) {
+ X509_NAME *nm;
+ X509_NAME *issuer;
+ BIGNUM *bn;
+ ASN1_INTEGER *serial;
+
+ nm = xmlSecSymbianCryptoX509NameRead(issuerName, xmlStrlen(issuerName));
+ if(!nm) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ NULL,
+ "xmlSecSymbianCryptoX509NameRead",
+ XMLSEC_ERRORS_R_XMLSEC_FAILED,
+ "issuer=%s",
+ xmlSecErrorsSafeString(issuerName));
+ return(NULL);
+ }
+
+ bn = BN_new();
+ if(!bn) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ NULL,
+ "BN_new",
+ XMLSEC_ERRORS_R_CRYPTO_FAILED,
+ XMLSEC_ERRORS_NO_MESSAGE);
+ X509_NAME_free(nm);
+ return(NULL);
+ }
+ if(BN_dec2bn(&bn, (char*)issuerSerial) == 0) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ NULL,
+ "BN_dec2bn",
+ XMLSEC_ERRORS_R_CRYPTO_FAILED,
+ XMLSEC_ERRORS_NO_MESSAGE);
+ BN_free(bn);
+ X509_NAME_free(nm);
+ return(NULL);
+ }
+
+ serial = BN_to_ASN1_INTEGER(bn, NULL);
+ if(!serial) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ NULL,
+ "BN_to_ASN1_INTEGER",
+ XMLSEC_ERRORS_R_CRYPTO_FAILED,
+ XMLSEC_ERRORS_NO_MESSAGE);
+ BN_free(bn);
+ X509_NAME_free(nm);
+ return(NULL);
+ }
+ BN_free(bn);
+
+
+ for(i = 0; i < certs->num; ++i) {
+ cert = ((X509**)(certs->data))[i];
+ if(ASN1_INTEGER_cmp(X509_get_serialNumber(cert), serial) != 0) {
+ continue;
+ }
+ issuer = X509_get_issuer_name(cert);
+ if(xmlSecSymbianCryptoX509NamesCompare(nm, issuer) == 0) {
+ ASN1_INTEGER_free(serial);
+ X509_NAME_free(nm);
+ return(cert);
+ }
+ }
+
+ X509_NAME_free(nm);
+ ASN1_INTEGER_free(serial);
+ } else if(ski) {
+ int len;
+ int index;
+ X509_EXTENSION *ext;
+ ASN1_OCTET_STRING *keyId;
+
+ /* our usual trick with base64 decode */
+ len = xmlSecBase64Decode(ski, (xmlSecByte*)ski, xmlStrlen(ski));
+ if(len < 0) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ NULL,
+ "xmlSecBase64Decode",
+ XMLSEC_ERRORS_R_XMLSEC_FAILED,
+ "ski=%s",
+ xmlSecErrorsSafeString(ski));
+ return(NULL);
+ }
+ for(i = 0; i < certs->num; ++i) {
+ cert = ((X509**)(certs->data))[i];
+ index = X509_get_ext_by_NID(cert, NID_subject_key_identifier, -1);
+ if(index >= 0) {
+ ext = X509_get_ext(cert, index);
+ if(ext){
+ keyId = X509V3_EXT_d2i(ext);
+ if((keyId) && (keyId->length == len) &&
+ (memcmp(keyId->data, ski, len) == 0)) {
+ M_ASN1_OCTET_STRING_free(keyId);
+ return(cert);
+ }
+ M_ASN1_OCTET_STRING_free(keyId);
+ }
+ }
+ }
+ }
+#endif //XMLSEC_FUTURE_SUPPORT
+ return(NULL);
+}
+
+/**
+ * xmlSecSymbianCryptoX509FindNextChainCert:
+ */
+static X509*
+xmlSecSymbianCryptoX509FindNextChainCert(STACK_OF(X509) *chain, X509 *cert) {
+ unsigned long certSubjHash;
+ int i;
+
+ xmlSecAssert2(chain, NULL);
+ xmlSecAssert2(cert, NULL);
+/*
+ certSubjHash = X509_subject_name_hash(cert);
+ for(i = 0; i < sk_X509_num(chain); ++i) {
+ if((sk_X509_value(chain, i) != cert) &&
+ (X509_issuer_name_hash(sk_X509_value(chain, i)) == certSubjHash)) {
+
+ return(sk_X509_value(chain, i));
+ }
+ }
+*/
+ return(NULL);
+}
+
+/**
+ * xmlSecSymbianCryptoX509VerifyCertAgainstCrls:
+ */
+static int
+xmlSecSymbianCryptoX509VerifyCertAgainstCrls(STACK_OF(X509_CRL) *crls, X509* cert) {
+ X509_NAME *issuer;
+ X509_CRL *crl = NULL;
+#ifdef XMLSEC_FUTURE_SUPPORT
+ X509_REVOKED *revoked;
+ int i, n;
+ int ret;
+
+ xmlSecAssert2(crls, -1);
+ xmlSecAssert2(cert, -1);
+
+ /*
+ * Try to retrieve a CRL corresponding to the issuer of
+ * the current certificate
+ */
+ n = sk_X509_CRL_num(crls);
+ for(i = 0; i < n; i++) {
+ crl = sk_X509_CRL_value(crls, i);
+ issuer = X509_CRL_get_issuer(crl);
+ if(xmlSecSymbianCryptoX509NamesCompare(X509_CRL_get_issuer(crl), issuer) == 0) {
+ break;
+ }
+ }
+ if((i >= n) || (!crl)){
+ /* no crls for this issuer */
+ return(1);
+ }
+
+ /*
+ * Check date of CRL to make sure it's not expired
+ */
+ ret = X509_cmp_current_time(X509_CRL_get_nextUpdate(crl));
+ if (ret == 0) {
+ /* crl expired */
+ return(1);
+ }
+
+ /*
+ * Check if the current certificate is revoked by this CRL
+ */
+ n = sk_num(X509_CRL_get_REVOKED(crl));
+ for (i = 0; i < n; i++) {
+ revoked = (X509_REVOKED *)sk_value(X509_CRL_get_REVOKED(crl), i);
+ if (ASN1_INTEGER_cmp(revoked->serialNumber, X509_get_serialNumber(cert)) == 0) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ NULL,
+ NULL,
+ XMLSEC_ERRORS_R_CERT_REVOKED,
+ XMLSEC_ERRORS_NO_MESSAGE);
+ return(0);
+ }
+ }
+#endif //XMLSEC_FUTURE_SUPPORT
+ return(1);
+}
+
+
+/**
+ * xmlSecSymbianCryptoX509NameRead:
+ */
+static X509_NAME *
+xmlSecSymbianCryptoX509NameRead(xmlSecByte *str, int len) {
+ xmlSecByte name[256];
+ xmlSecByte value[256];
+ int nameLen, valueLen;
+ X509_NAME *nm = NULL;
+
+ xmlSecAssert2(str, NULL);
+
+#ifdef XMLSEC_FUTURE_SUPPORT
+ nm = X509_NAME_new();
+ if(!nm) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ NULL,
+ "X509_NAME_new",
+ XMLSEC_ERRORS_R_CRYPTO_FAILED,
+ XMLSEC_ERRORS_NO_MESSAGE);
+ return(NULL);
+ }
+
+ while(len > 0) {
+ /* skip spaces after comma or semicolon */
+ while((len > 0) && isspace(*str)) {
+ ++str; --len;
+ }
+
+ nameLen = xmlSecSymbianCryptoX509NameStringRead(&str, &len, name, sizeof(name), '=', 0);
+ if(nameLen < 0) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ NULL,
+ "xmlSecSymbianCryptoX509NameStringRead",
+ XMLSEC_ERRORS_R_XMLSEC_FAILED,
+ XMLSEC_ERRORS_NO_MESSAGE);
+ X509_NAME_free(nm);
+ return(NULL);
+ }
+ name[nameLen] = '\0';
+ if(len > 0) {
+ ++str; --len;
+ if((*str) == '\"') {
+ ++str; --len;
+ valueLen = xmlSecSymbianCryptoX509NameStringRead(&str, &len,
+ value, sizeof(value), '"', 1);
+ if(valueLen < 0) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ NULL,
+ "xmlSecSymbianCryptoX509NameStringRead",
+ XMLSEC_ERRORS_R_XMLSEC_FAILED,
+ XMLSEC_ERRORS_NO_MESSAGE);
+ X509_NAME_free(nm);
+ return(NULL);
+ }
+
+ /* skip quote */
+ if((len <= 0) || ((*str) != '\"')) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ NULL,
+ NULL,
+ XMLSEC_ERRORS_R_INVALID_DATA,
+ "quote is expected:%s",
+ xmlSecErrorsSafeString(str));
+ X509_NAME_free(nm);
+ return(NULL);
+ }
+ ++str; --len;
+
+ /* skip spaces before comma or semicolon */
+ while((len > 0) && isspace(*str)) {
+ ++str; --len;
+ }
+ if((len > 0) && ((*str) != ',')) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ NULL,
+ NULL,
+ XMLSEC_ERRORS_R_INVALID_DATA,
+ "comma is expected:%s",
+ xmlSecErrorsSafeString(str));
+ X509_NAME_free(nm);
+ return(NULL);
+ }
+ if(len > 0) {
+ ++str; --len;
+ }
+ type = MBSTRING_ASC;
+ } else if((*str) == '#') {
+ /* Not implemented currently */
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ NULL,
+ NULL,
+ XMLSEC_ERRORS_R_INVALID_DATA,
+ "reading octect values is not implemented yet");
+ X509_NAME_free(nm);
+ return(NULL);
+ } else {
+ valueLen = xmlSecSymbianCryptoX509NameStringRead(&str, &len,
+ value, sizeof(value), ',', 1);
+ if(valueLen < 0) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ NULL,
+ "xmlSecSymbianCryptoX509NameStringRead",
+ XMLSEC_ERRORS_R_XMLSEC_FAILED,
+ XMLSEC_ERRORS_NO_MESSAGE);
+ X509_NAME_free(nm);
+ return(NULL);
+ }
+ type = MBSTRING_ASC;
+ }
+ } else {
+ valueLen = 0;
+ }
+ value[valueLen] = '\0';
+ if(len > 0) {
+ ++str; --len;
+ }
+ X509_NAME_add_entry_by_txt(nm, (char*)name, type, value, valueLen, -1, 0);
+ }
+#endif //XMLSEC_FUTURE_SUPPORT
+ return(nm);
+}
+
+
+
+/**
+ * xmlSecSymbianCryptoX509NameStringRead:
+ */
+static int
+xmlSecSymbianCryptoX509NameStringRead(xmlSecByte **str, int *strLen,
+ xmlSecByte *res, int resLen,
+ xmlSecByte delim, int ingoreTrailingSpaces) {
+ xmlSecByte *p, *q, *nonSpace;
+
+ xmlSecAssert2(str, -1);
+ xmlSecAssert2(strLen, -1);
+ xmlSecAssert2(res, -1);
+
+ p = (*str);
+ nonSpace = q = res;
+ while(((p - (*str)) < (*strLen)) && ((*p) != delim) && ((q - res) < resLen)) {
+ if((*p) != '\\') {
+ if(ingoreTrailingSpaces && !isspace(*p)) nonSpace = q;
+ *(q++) = *(p++);
+ } else {
+ ++p;
+ nonSpace = q;
+ if(xmlSecIsHex((*p))) {
+ if((p - (*str) + 1) >= (*strLen)) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ NULL,
+ NULL,
+ XMLSEC_ERRORS_R_INVALID_DATA,
+ "two hex digits expected");
+ return(-1);
+ }
+ *(q++) = xmlSecGetHex(p[0]) * 16 + xmlSecGetHex(p[1]);
+ p += 2;
+ } else {
+ if(((++p) - (*str)) >= (*strLen)) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ NULL,
+ NULL,
+ XMLSEC_ERRORS_R_INVALID_DATA,
+ "escaped symbol missed");
+ return(-1);
+ }
+ *(q++) = *(p++);
+ }
+ }
+ }
+ if(((p - (*str)) < (*strLen)) && ((*p) != delim)) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ NULL,
+ NULL,
+ XMLSEC_ERRORS_R_INVALID_SIZE,
+ "buffer is too small");
+ return(-1);
+ }
+ (*strLen) -= (p - (*str));
+ (*str) = p;
+ return((ingoreTrailingSpaces) ? nonSpace - res + 1 : q - res);
+}
+
+static
+int xmlSecSymbianCryptoX509_NAME_cmp(const X509_NAME *a, const X509_NAME *b) {
+ int i,ret;
+/*
+ const X509_NAME_ENTRY *na,*nb;
+
+ xmlSecAssert2(a != NULL, -1);
+ xmlSecAssert2(b != NULL, 1);
+
+ if (sk_X509_NAME_ENTRY_num(a->entries) != sk_X509_NAME_ENTRY_num(b->entries)) {
+ return sk_X509_NAME_ENTRY_num(a->entries) - sk_X509_NAME_ENTRY_num(b->entries);
+ }
+
+ for (i=sk_X509_NAME_ENTRY_num(a->entries)-1; i>=0; i--) {
+ na=sk_X509_NAME_ENTRY_value(a->entries,i);
+ nb=sk_X509_NAME_ENTRY_value(b->entries,i);
+
+ ret = xmlSecSymbianCryptoX509_NAME_ENTRY_cmp(&na, &nb);
+ if(ret != 0) {
+ return(ret);
+ }
+ }
+*/
+ return(0);
+}
+
+
+/**
+ * xmlSecSymbianCryptoX509NamesCompare:
+ *
+ * we have to sort X509_NAME entries to get correct results.
+ * This is ugly but SymbianCrypto does not support it
+ */
+static int
+xmlSecSymbianCryptoX509NamesCompare(X509_NAME *a, X509_NAME *b) {
+ X509_NAME *a1 = NULL;
+ X509_NAME *b1 = NULL;
+ int ret = -1;
+
+ xmlSecAssert2(a, -1);
+ xmlSecAssert2(b, 1);
+#ifdef XMLSEC_FUTURE_SUPPORT
+ a1 = X509_NAME_dup(a);
+ if(!a1) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ NULL,
+ "X509_NAME_dup",
+ XMLSEC_ERRORS_R_CRYPTO_FAILED,
+ XMLSEC_ERRORS_NO_MESSAGE);
+ return(-1);
+ }
+ b1 = X509_NAME_dup(b);
+ if(!b1) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ NULL,
+ "X509_NAME_dup",
+ XMLSEC_ERRORS_R_CRYPTO_FAILED,
+ XMLSEC_ERRORS_NO_MESSAGE);
+ return(1);
+ }
+
+ /* sort both */
+ sk_X509_NAME_ENTRY_set_cmp_func(a1->entries, xmlSecSymbianCryptoX509_NAME_ENTRY_cmp);
+ sk_X509_NAME_ENTRY_sort(a1->entries);
+ sk_X509_NAME_ENTRY_set_cmp_func(b1->entries, xmlSecSymbianCryptoX509_NAME_ENTRY_cmp);
+ sk_X509_NAME_ENTRY_sort(b1->entries);
+
+ /* actually compare */
+ ret = xmlSecSymbianCryptoX509_NAME_cmp(a1, b1);
+
+ /* cleanup */
+ X509_NAME_free(a1);
+ X509_NAME_free(b1);
+#endif //XMLSEC_FUTURE_SUPPORT
+ return(ret);
+}
+
+
+/**
+ * xmlSecSymbianCryptoX509_NAME_ENTRY_cmp:
+ */
+#ifdef XMLSEC_FUTURE_SUPPORT
+static int
+xmlSecSymbianCryptoX509_NAME_ENTRY_cmp(const X509_NAME_ENTRY **a, const X509_NAME_ENTRY **b) {
+ int ret;
+
+ xmlSecAssert2(a, -1);
+ xmlSecAssert2(b, 1);
+ xmlSecAssert2((*a), -1);
+ xmlSecAssert2((*b), 1);
+
+ /* first compare values */
+ if((!((*a)->value)) && ((*b)->value)) {
+ return(-1);
+ } else if(((*a)->value) && (!((*b)->value))) {
+ return(1);
+ } else if((!((*a)->value)) && (!((*b)->value))) {
+ return(0);
+ }
+
+ ret = (*a)->value->length - (*b)->value->length;
+ if(ret != 0) {
+ return(ret);
+ }
+
+ ret = memcmp((*a)->value->data, (*b)->value->data, (*a)->value->length);
+ if(ret != 0) {
+ return(ret);
+ }
+
+ /* next compare names */
+ return(OBJ_cmp((*a)->object, (*b)->object));
+}
+#endif //XMLSEC_FUTURE_SUPPORT
+
+
+#endif /* XMLSEC_NO_X509 */
+
+